I recently wrote a fast and dirty proxy server with a proxy concept in C # as part of trying to get a Java web application to communicate with an outdated VB6 application located on another server. This is ridiculously simple:
The proxy server and clients use the same message format; in the code, I use the class ProxyMessageto represent both requests from clients and responses generated by the server:
public class ProxyMessage
{
int Length;
string Body;
WriteToStream(Stream stream) { ... }
}
Messages are as simple as they can be: body length + message body.
I have a separate class ProxyClientthat represents a connection to a client. It handles all interactions between the proxy and one client.
, , ? , , , , , . TcpClient.BeginRead .
, BeginRead, . , , " ", , , (, , ?).
private enum BufferStates
{
GetMessageLength,
GetMessageBody
}
byte[] _buffer = new byte[4];
int _totalBytesRead = 0;
BufferStates _bufferState = BufferStates.GetMessageLength;
private void ReadCallback(IAsyncResult ar)
{
try
{
int bytesRead = _tcpClient.GetStream().EndRead(ar);
if (bytesRead == 0)
{
this.Dispose();
return;
}
ProxyMessage message = (ProxyMessage)ar.AsyncState;
if(message == null)
message = new ProxyMessage();
switch (_bufferState)
{
case BufferStates.GetMessageLength:
_totalBytesRead += bytesRead;
if (_totalBytesRead == 4)
{
int length = BitConverter.ToInt32(_buffer, 0);
message.Length = length;
_totalBytesRead = 0;
_buffer = new byte[message.Length];
_bufferState = BufferStates.GetMessageBody;
}
break;
case BufferStates.GetMessageBody:
string bodySegment = Encoding.ASCII.GetString(_buffer, _totalBytesRead, bytesRead);
_totalBytesRead += bytesRead;
message.Body += bodySegment;
if (_totalBytesRead >= message.Length)
{
ProxyMessage response = new ProxyMessage();
OnReceiveMessage(this, new ProxyMessageEventArgs(message, response));
response.WriteToStream(_tcpClient.GetStream());
message = new ProxyMessage();
_totalBytesRead = 0;
_buffer = new byte[4];
_bufferState = BufferStates.GetMessageLength;
}
break;
}
_tcpClient.GetStream().BeginRead(_buffer, 0, _buffer.Length, this.ReadCallback, message);
}
catch
{
}
}
, MessageBuffer . MessageBuffer , BufferState, , , ProxyClient -, .