我正在开发一个接受来自多个客户端的连接的代理。代理检查来自客户端的有效令牌,如果找到令牌,它允许客户端连接到服务器。
我正在使用此链接中的 SocketAsyncEventArgs、BufferManager 和其他详细信息
代码如下。
我正在使用 acceptEventArgs 接受来自客户端的新连接,并使用 connectEventArgs 连接到实际服务器。如何将接收到的数据从 acceptEventArgs (AcceptSocket) 发送到 connectedEventArgs (ConnectedSocket)
//接受套接字后的代码
私有无效 ProcessAccept(SocketAsyncEventArgs acceptEventArgs){
if (acceptEventArgs.SocketError != SocketError.Success)
{
// Loop back to post another accept op. Notice that we are NOT
// passing the SAEA object here.
LoopToStartAccept();
//AcceptOpUserToken theAcceptOpToken = (AcceptOpUserToken)acceptEventArgs.UserToken;
//Console.WriteLine("SocketError, accept id " + theAcceptOpToken.TokenId);
//destroy the socket, since it could be bad.
HandleBadAccept(acceptEventArgs);
return;
}
Int32 max = Program.maxSimultaneousClientsThatWereConnected;
Int32 numberOfConnectedSockets = Interlocked.Increment(ref this.numberOfAcceptedSockets);
if (numberOfConnectedSockets > max)
{
Interlocked.Increment(ref Program.maxSimultaneousClientsThatWereConnected);
}
Console.WriteLine("Simultaneous connections {0} ", max.ToString());
LoopToStartAccept();
// Get a SocketAsyncEventArgs object from the pool of receive/send op
//SocketAsyncEventArgs objects
SocketAsyncEventArgs receiveSendEventArgs = this.poolOfRecSendEventArgs.Pop();
//A new socket was created by the AcceptAsync method.
//object which will do receive/send.
receiveSendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket;
//We have handed off the connection info from the
//accepting socket to the receiving socket. So, now we can
//put the SocketAsyncEventArgs object that did the accept operation
//back in the pool for them.
acceptEventArgs.AcceptSocket = null;
this.poolOfAcceptEventArgs.Push(acceptEventArgs);
//Accepting has completed now connect to the TestServer Server
StartConnecting(receiveSendEventArgs);
}
private void LoopToStartAccept()
{
StartAccepting();
}
/// <summary>
/// Connects to the TestServer Server
/// </summary>
/// <param name="acceptArgs"></param>
internal void StartConnecting(SocketAsyncEventArgs receiveSendEventArgs)
{
SocketAsyncEventArgs connectEventArgs;
//Get a SocketAsyncEventArgs object to connect to the TestServer Server.
//Get it from the pool if there is more than one in the pool.
//using 1 as the lower limit for safety sake
if (this.poolOfConnectEventArgs.Count > 1)
{
try
{
connectEventArgs = this.poolOfConnectEventArgs.Pop();
}
//or make a new one.
catch
{
connectEventArgs = CreateNewSaeaForConnect(poolOfConnectEventArgs);
}
}
//or make a new one.
else
{
connectEventArgs = CreateNewSaeaForConnect(poolOfConnectEventArgs);
}
//connect to the server
IPAddress ipAddress_TestServer_ADS = new IPAddress(new byte[] { 192, 201, 240, 89 });
int port = 8085;
// Establish the local endpoint for the socket.
IPEndPoint HostEndPoint = new IPEndPoint(ipAddress_TestServer_ADS, port);
Socket serverSocket;
// Create a TCP/IP socket.
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
connectEventArgs.RemoteEndPoint = HostEndPoint;
//Store the receive Send event args in the UserToken
connectEventArgs.UserToken = receiveSendEventArgs;
//bool completedSynchronously = receiveSendEventArgs.AcceptSocket.ConnectAsync(connectEventArgs);
bool completedSynchronously = serverSocket.ConnectAsync(connectEventArgs);
if (!completedSynchronously)
{
ProcessConnection(connectEventArgs);
}
}
private void ConnectEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
Console.WriteLine("ConnectEventArg_Completed, id ");
ProcessConnection(e);
}
private void ProcessConnection(SocketAsyncEventArgs connectEventArgs)
{
//get the receiveSendEventArgs
SocketAsyncEventArgs receiveSendEventArgs = (SocketAsyncEventArgs)connectEventArgs.UserToken;
// This is when there was an error with the connect operation.Close the socket
if (connectEventArgs.SocketError != SocketError.Success)
{
//destroy the server socket, since it could be bad.
HandleBadConnect(connectEventArgs);
//destroy the client socket since its of no use either
return;
}
Console.WriteLine("Connected to TestServer Server ");
//Read data from the client socket and the Server Socket
StartReceive(receiveSendEventArgs, connectEventArgs);
}
// Set the receive buffer and post a receive op.
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs,SocketAsyncEventArgs TestServerreceiveSendEventArgs)
{
//Create a state object to store the state
StateObject state = new StateObject();
//Set the buffer for the receive operation.
receiveSendEventArgs.SetBuffer(state.clientReadBuffer, 0, StateObject.BUFFER_SIZE);
//Set the buffer for the receive from TestServer operation.
TestServerreceiveSendEventArgs.SetBuffer(state.serverReadBuffer, 0, StateObject.BUFFER_SIZE);
state.clientSocketAsyncEventArgs = receiveSendEventArgs;
state.serverSocketAsyncEventArgs = TestServerreceiveSendEventArgs;
receiveSendEventArgs.UserToken = state;
TestServerreceiveSendEventArgs.UserToken = state;
// Post async receive operation on the socket.
bool completedClientRecieveSynchronously = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
bool completedServerReceiveSynchronously = TestServerreceiveSendEventArgs.ConnectSocket.ReceiveAsync(TestServerreceiveSendEventArgs);
if (!completedClientRecieveSynchronously)
{
ProcessClientReceive(receiveSendEventArgs);
}
if (!completedServerReceiveSynchronously)
{
ProcessServerReceive(TestServerreceiveSendEventArgs);
}
}
private void ProcessClientReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
//check for Token and write to the Server socket
// If there was a socket error, close the connection.
if (receiveSendEventArgs.SocketError != SocketError.Success)
{
CloseClientSocket(receiveSendEventArgs);
return;
}
// If no data was received, close the connection. This is a NORMAL
// situation that shows when the client has finished sending data.
if (receiveSendEventArgs.BytesTransferred == 0)
{
CloseClientSocket(receiveSendEventArgs);
return;
}
if (receiveSendEventArgs.BytesTransferred > 0) //write to the server side socket
{
//How do I write to the server socket ..do not have an handler to the server socket.
}
}
private void ProcessServerReceive(SocketAsyncEventArgs TestServerreceiveSendEventArgs)
{
//Write to the client socket
}