-
Notifications
You must be signed in to change notification settings - Fork 0
/
SocketListener.cs
148 lines (124 loc) · 4.6 KB
/
SocketListener.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace kb
{
class StateObject
{
public Socket workSocket = null;
public int BufferSize;
public byte[] buffer;
public int startIndex = 0;
public StateObject (int bufferSize)
{
BufferSize = bufferSize;
buffer = new byte[bufferSize];
}
}
class SocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public static void StartListening ()
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = null;
foreach (IPAddress ip in ipHostInfo.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
ipAddress = ip;
break;
}
}
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 44444);
Console.WriteLine("Listening at {0}", localEndPoint.ToString());
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
Console.WriteLine("Waiting for a connection...");
Socket handler = listener.Accept();
Console.WriteLine("Connected. Socket: {0}", handler.LocalEndPoint);
while (true)
{
// Set the event to nonsignaled state
allDone.Reset();
StateObject state = new StateObject(4);
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, state.BufferSize, 0, new AsyncCallback(ReadBufferSizeCallback), state);
// Wait until one data is received.
allDone.WaitOne();
if (!SocketExtensions.IsConnected(handler))
{
break;
}
}
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void ReadBufferSizeCallback (IAsyncResult ar)
{
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (BitConverter.IsLittleEndian)
Array.Reverse(state.buffer);
int bufferSize = BitConverter.ToInt32(state.buffer, 0);
StateObject _state = new StateObject(bufferSize);
_state.workSocket = handler;
handler.BeginReceive(_state.buffer, 0, _state.BufferSize, 0, new AsyncCallback(ReadCallback), _state);
}
else
{
allDone.Set();
}
}
public static void ReadCallback (IAsyncResult ar)
{
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead <= 0) {
allDone.Set();
return;
}
if (bytesRead < state.BufferSize)
{
state.BufferSize -= bytesRead;
state.startIndex += bytesRead;
handler.BeginReceive(state.buffer, state.startIndex, state.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
{
// Signal the main thread to continue.
allDone.Set();
VirtualInput vi = VirtualInput.Parser.ParseFrom(state.buffer);
Console.WriteLine(vi.ToString());
}
}
}
static class SocketExtensions
{
public static bool IsConnected(this Socket socket)
{
try
{
return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
}
catch (SocketException) { return false; }
}
}
}