複数のクライアントからの接続を受け入れるプロキシを開発しています。プロキシはクライアントからの有効なトークンをチェックし、トークンが見つかった場合、クライアントがサーバーに接続できるようにします。
このリンクからSocketAsyncEventArgs、BufferManager、およびその他の詳細を使用しています
コードは以下の通りです。
クライアントからの新しい接続を受け入れるためにacceptEventArgsを使用し、実際のサーバーに接続するためにconnectEventArgsを使用しています。受信したデータを acceptEventArgs (AcceptSocket) から connectedEventArgs (ConnectedSocket) に送信するにはどうすればよいですか?
//ソケットを受け入れた後のコード
private void 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
}