110,499
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Windows.Forms;
namespace IOCPServer
{
public class ClientToken
{
public Socket ConnectSocket;
public SocketAsyncEventArgs ReceiveEventArgs;
public SocketAsyncEventArgs SendEventArgs;
protected byte[] RecvBuffer;
public ClientToken()
{
ReceiveEventArgs = new SocketAsyncEventArgs();
ReceiveEventArgs.UserToken = this;
SendEventArgs = new SocketAsyncEventArgs();
SendEventArgs.UserToken = this;
RecvBuffer = new byte[1024];
ReceiveEventArgs.SetBuffer(RecvBuffer, 0, RecvBuffer.Length);
}
}
public class IOCPServer
{
bool IsInit;
bool IsRun;
Socket listenSocket;
List<ClientToken> ClientList;
Object m_Mutex;
public void Init()
{
if (IsInit == true)
return;
m_Mutex = null;
ClientList = new List<ClientToken>(1);
IsInit = true;
}
public void UnInit()
{
if (IsInit == false)
return;
ClientList.Clear();
IsInit = false;
}
public bool Start(IPEndPoint localEndPoint)
{
if (IsRun)
return true;
try
{
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
listenSocket.Listen(100);
}
catch (SocketException e)
{
if (e.NativeErrorCode == 10048)
MessageBox.Show("监听端口已经被占用", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
else
MessageBox.Show(e.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
StartAccept(null);
IsRun = true;
return true;
}
public void Stop()
{
if (IsRun == false)
return;
try
{
listenSocket.Close();
}
catch (Exception E)
{
}
IsRun = false;
}
public void StartAccept(SocketAsyncEventArgs acceptEventArgs)
{
if (acceptEventArgs == null)
{
acceptEventArgs = new SocketAsyncEventArgs();
acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
}
else
{
acceptEventArgs.AcceptSocket = null; //释放上次绑定的Socket,等待下一个Socket连接
}
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArgs);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArgs);
}
}
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs)
{
try
{
if (acceptEventArgs.AcceptSocket.Connected == true)
ProcessAccept(acceptEventArgs);
}
catch (Exception E)
{
}
}
private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
{
ClientToken cliToken = new ClientToken();
cliToken.ReceiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
cliToken.SendEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
cliToken.ConnectSocket = acceptEventArgs.AcceptSocket;
ClientList.Add(cliToken);
try
{
bool willRaiseEvent = cliToken.ConnectSocket.ReceiveAsync(cliToken.ReceiveEventArgs); //投递接收请求
if (!willRaiseEvent)
{
lock (cliToken)
{
ProcessReceive(cliToken.ReceiveEventArgs);
}
}
}
catch (Exception E)
{
}
StartAccept(acceptEventArgs); //把当前异步事件释放,等待下次连接
}
void IO_Completed(object sender, SocketAsyncEventArgs asyncEventArgs)
{
ClientToken cliToken = (ClientToken)asyncEventArgs.UserToken;
try
{
lock (cliToken)
{
if (asyncEventArgs.LastOperation == SocketAsyncOperation.Receive)
ProcessReceive(asyncEventArgs);
}
}
catch (Exception E)
{
}
}
private void ProcessReceive(SocketAsyncEventArgs receiveEventArgs)
{
ClientToken cliToken = (ClientToken)receiveEventArgs.UserToken;
if (cliToken.ConnectSocket == null)
return;
if (cliToken.ReceiveEventArgs.BytesTransferred > 0 && cliToken.ReceiveEventArgs.SocketError == SocketError.Success)
{
SendAsync(cliToken.ConnectSocket,cliToken.SendEventArgs,cliToken.ReceiveEventArgs.Buffer,cliToken.ReceiveEventArgs.Offset,cliToken.ReceiveEventArgs.BytesTransferred);
bool willRaiseEvent = cliToken.ConnectSocket.ReceiveAsync(cliToken.ReceiveEventArgs); //投递接收请求
if (!willRaiseEvent)
ProcessReceive(cliToken.ReceiveEventArgs);
}
else
{
CloseClientSocket(cliToken);
}
}
public void CloseClientSocket(ClientToken cliToken)
{
if (cliToken.ConnectSocket == null)
return;
try
{
cliToken.ConnectSocket.Shutdown(SocketShutdown.Both);
}
catch (Exception E)
{
}
cliToken.ConnectSocket.Close();
cliToken.ConnectSocket = null;
ClientList.Remove(cliToken);
}
public bool SendAsync(Socket connectSocket, SocketAsyncEventArgs sendEventArgs, byte[] buffer, int offset, int count)
{
if (connectSocket == null)
return false;
bool willRaiseEvent = true;
try
{
sendEventArgs.SetBuffer(buffer, offset, count);
willRaiseEvent = connectSocket.SendAsync(sendEventArgs);
}
catch (Exception E)
{
return false;
}
return false;
}
}
}