以下代码创建套接字服务器和客户端
我启动服务器,如果我一个接一个地启动客户端它可以正常工作
如果我立即启动三个客户端,那么对于一个或多个客户端,不会触发BeginAccept事件
下面的结果是在执行下面的代码后
服务器已启动
服务器正在等待连接......
客户端0.0.0.0:6352请求连接
客户端0.0.0.0:6353请求连接
客户端127.0.0.1:6351请求连接
客户端127.0.0.1:6351已连接
客户端127.0.0.1:6352已连接
客户端127.0.0.1:6353已连接
ServerOnClientConnection客户端:127.0.0.1:6351
服务器正在等待连接......
ServerOnClientConnection客户端:127.0.0.1:6353
代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Test {
public class TestSockets {
#region server
Socket serverSocket;
bool serverIsAlive;
public ManualResetEvent waitForConnection = new ManualResetEvent(false);
private Encoding encod = Encoding.Unicode;
public void ServerStartInThread() {
byte[] bytes = new Byte[1024];
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 5500);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket = socket;
try {
socket.Bind(localEndPoint);
socket.Listen(100);
Thread pollThread = new Thread(delegate () {
serverIsAlive = true; // needs if reopen
SendMessage("Server Started");
while (serverIsAlive) {
try {
SendMessage("Server is waiting for a connection...");
socket.BeginAccept(new AsyncCallback(ServerOnClientConnection), socket);
waitForConnection.Reset();
waitForConnection.WaitOne();
}
catch (Exception ex) {
SendMessage("Server: " + ex.ToString());
}
}
SendMessage("Server Stopped");
socket.Close();
}) {
Name = "SocketServer"
};
pollThread.Start();
}
catch (Exception ex) {
SendMessage("Server: " + ex.ToString());
}
}
public void ServerOnClientConnection(IAsyncResult ar) {
try {
Socket listener = (Socket)ar.AsyncState;
Socket clientSocket = listener.EndAccept(ar);
SendMessage("ServerOnClientConnection Client: " + clientSocket.RemoteEndPoint.ToString());
StateObject state = new StateObject() {
socket = clientSocket
};
clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ServerReceiveCallback), state);
waitForConnection.Set();
}
catch (Exception ex) {
SendMessage("ServerOnClientConnection: " + ex.ToString());
}
}
public void ServerReceiveCallback(IAsyncResult ar) {
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
try {
if (socket == null) return;
if (!socket.Connected) {
return;
}
int bytesRead = socket.EndReceive(ar);
if (bytesRead > 0) {
state.sb.Append(encod.GetString(state.buffer, 0, bytesRead));
socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ServerReceiveCallback), state);
}
}
catch (Exception ex) {
SendMessage("ServerReceiveCallback: " + ex.ToString());
}
}
#endregion
#region client
private Socket client;
private bool isAlive = false;
private ManualResetEvent connectDone = new ManualResetEvent(false);
public void StartInThread() {
try {
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 5500);
Thread pollThread = new Thread(delegate () {
isAlive = true;
while (isAlive) {
try {
if (client != null && client.Connected) {
continue;
}
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP, new AsyncCallback(ClientConnectCallback), client);
SendMessage(string.Format("Client {0} requests connection", client.LocalEndPoint.ToString()));
connectDone.Reset();
connectDone.WaitOne(3000, false);
if (client.Connected) {
StateObject state = new StateObject() {
socket = client
};
SendMessage(string.Format("Client {0} connected", client.LocalEndPoint.ToString()));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ClientReceiveCallback), state);
}
}
catch (Exception ex) {
SendMessage("ClientStartInThread1: " + ex.ToString());
}
}
SendMessage("Client Disconnected");
}) {
Name = "ClientThread"
};
pollThread.Start();
}
catch (Exception ex) {
SendMessage("ClientStartInThread2: " + ex.ToString());
}
}
private void ClientConnectCallback(IAsyncResult ar) {
try {
Socket socket = (Socket)ar.AsyncState;
socket.EndConnect(ar);
connectDone.Set();
}
catch (Exception ex) {
SendMessage("ClientConnectCallback: " + ex.ToString());
}
}
private void ClientReceiveCallback(IAsyncResult ar) {
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
if (socket == null || !socket.Connected) return;
try {
int bytesRead = socket.EndReceive(ar);
if (bytesRead > 0) {
state.sb.Append(encod.GetString(state.buffer, 0, bytesRead));
socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ClientReceiveCallback), state);
}
else {
socket.Close();
}
}
catch (Exception ex) {
SendMessage("ClientReceiveCallback: " + ex.ToString());
socket.Close();
}
}
#endregion
private void SendMessage(string v) {
System.Diagnostics.Debug.WriteLine(v);
}
public static void Start() {
TestSockets server = new TestSockets();
server.ServerStartInThread();
TestSockets c1 = new TestSockets();
c1.StartInThread();
TestSockets c2 = new TestSockets();
c2.StartInThread();
TestSockets c3 = new TestSockets();
c3.StartInThread();
}
}
public class StateObject {
public Socket socket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
}