C# 傳統的 Socket 會在斷線時讓系統卡住十幾秒,就算用 try catch 機制也無法避免這個問題。而非同步連線內部的機制就不會讓系統卡住,以下是非同步連線寫出的函式。
1
2
3
4
5
6
7
8
9
10
11
12
13
// Asynchronous Socket
public Socket AsyncConnect(string ip, string port) {
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult result = socket.BeginConnect(ip, Int32.Parse(port), null, null);
result.AsyncWaitHandle.WaitOne(500, true); // Timeout 500 ms
if (socket.Connected) {
socket.EndConnect(result);
return socket;
} else {
socket.Close();
return null;
}
}
以下是調用方式,可以用 netcat
作為 server 測試。
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
public int SomeFunction() {
string IP = "127.0.0.1";
int PORT = 6666;
int BUFFERSIZE = 1024;
try {
// Asynchronous Socket Here
sock = AsyncConnect(IP, PORT.ToString());
if (sock == null) {
return -1;
} else {
// Send Data
sock.Send(Encoding.ASCII.GetBytes("Hello World!"));
// Receive Data
byte[] buffer = new byte[BUFFERSIZE];
int count = sock.Receive(buffer);
string recv = Encoding.ASCII.GetString(buffer, 0, count - 1);
}
sock.Close();
return 0;
} catch (Exception ex) {
if (sock != null)
sock.Close();
}
return -1;
}