Merge pull request #3142 from henricm/fix-for-win-mono_string_to_utf8
[mono.git] / mcs / class / System / Test / System.Net.Sockets / SocketAsyncTest.cs
1 using System;
2 using System.Collections;
3 using System.Threading;
4 using System.Net;
5 using System.Net.Sockets;
6 using NUnit.Framework;
7
8 namespace MonoTests.System.Net.Sockets
9 {
10         [TestFixture]
11         public class SocketAsyncTest
12         {
13                 Socket serverSocket;
14                 Socket clientSocket;
15                 ManualResetEvent readyEvent;
16                 ManualResetEvent mainEvent;
17                 Exception error;
18
19                 [TestFixtureSetUp]
20                 public void SetUp ()
21                 {
22                         readyEvent = new ManualResetEvent (false);
23                         mainEvent = new ManualResetEvent (false);
24
25                         ThreadPool.QueueUserWorkItem (_ => DoWork ());
26                         readyEvent.WaitOne ();
27
28                         clientSocket = new Socket (
29                                 AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
30                         clientSocket.Connect (serverSocket.LocalEndPoint);
31                         clientSocket.NoDelay = true;
32                 }
33
34                 [TestFixtureTearDown]
35                 public void TearDown ()
36                 {
37                         if (serverSocket != null)
38                                 serverSocket.Close ();
39                         readyEvent.Close ();
40                         mainEvent.Close ();
41                 }
42
43                 void DoWork ()
44                 {
45                         serverSocket = new Socket (
46                                 AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
47                         serverSocket.Bind (new IPEndPoint (IPAddress.Loopback, 0));
48                         serverSocket.Listen (1);
49
50                         var async = new SocketAsyncEventArgs ();
51                         async.Completed += (s,e) => OnAccepted (e);
52
53                         readyEvent.Set ();
54
55                         if (!serverSocket.AcceptAsync (async))
56                                 OnAccepted (async);
57                 }
58
59                 void OnAccepted (SocketAsyncEventArgs e)
60                 {
61                         var acceptSocket = e.AcceptSocket;
62
63                         try {
64                                 var header = new byte [4];
65                                 acceptSocket.Receive (header);
66                                 if ((header [0] != 0x12) || (header [1] != 0x34) ||
67                                     (header [2] != 0x56) || (header [3] != 0x78))
68                                         throw new InvalidOperationException ();
69                         } catch (Exception ex) {
70                                 error = ex;
71                                 return;
72                         }
73
74                         var recvAsync = new SocketAsyncEventArgs ();
75                         recvAsync.Completed += (sender, args) => OnReceived (args);
76                         recvAsync.SetBuffer (new byte [4], 0, 4);
77                         if (!acceptSocket.ReceiveAsync (recvAsync))
78                                 OnReceived (recvAsync);
79
80                         mainEvent.Set ();
81                 }
82
83                 void OnReceived (SocketAsyncEventArgs e)
84                 {
85                         if (e.SocketError != SocketError.Success)
86                                 error = new SocketException ((int) e.SocketError);
87                         else if (e.Buffer [0] != 0x9a)
88                                 error = new InvalidOperationException ();
89
90                         mainEvent.Set ();
91                 }
92
93                 [Test]
94                 [Category("Test")]
95                 public void SendAsync ()
96                 {
97                         var buffer = new byte [] { 0x12, 0x34, 0x56, 0x78 };
98                         var m = new ManualResetEvent (false);
99                         var e = new SocketAsyncEventArgs ();
100                         e.SetBuffer (buffer, 0, buffer.Length);
101                         e.Completed += (s,o) => {
102                                 if (o.SocketError != SocketError.Success)
103                                         error = new SocketException ((int)o.SocketError);
104                                 m.Set ();
105                         };
106                         bool res = clientSocket.SendAsync (e);
107                         if (res) {
108                                 if (!m.WaitOne (1500))
109                                         Assert.Fail ("Timeout #1");
110                         }
111
112                         if (!mainEvent.WaitOne (1500))
113                                 Assert.Fail ("Timeout #2");
114                         if (error != null)
115                                 throw error;
116
117                         m.Reset ();
118                         mainEvent.Reset ();
119
120                         buffer [0] = 0x9a;
121                         buffer [1] = 0xbc;
122                         buffer [2] = 0xde;
123                         buffer [3] = 0xff;
124                         res = clientSocket.SendAsync (e);
125                         if (res) {
126                                 if (!m.WaitOne (1500))
127                                         Assert.Fail ("Timeout #3");
128                         }
129
130                         if (!mainEvent.WaitOne (1500))
131                                 Assert.Fail ("Timeout #4");
132                         if (error != null)
133                                 throw error;
134                 }
135         }
136 }