我已经实现了这个 C# 客户端,它与我在 Java 中创建的另一台服务器的异步连接进行通信。这是客户端:
public class NetworkTransaction
{
private GenericRequest request;
private const string serverName = "192.168.1.101";
private const int serverPort = 7777;
private const int TIMEOUT_MILLISECONDS = 3000;
private Delegate method;
public NetworkTransaction(GenericRequest request, Delegate method)
{
this.request = request;
this.method = method;
}
public void SendRequest()
{
SocketAsyncEventArgs connectionOperation = new SocketAsyncEventArgs();
DnsEndPoint hostEntry = new DnsEndPoint(serverName, serverPort);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connectionOperation.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed);
connectionOperation.RemoteEndPoint = hostEntry;
connectionOperation.UserToken = socket;
try
{
socket.ConnectAsync(connectionOperation);
}
catch (SocketException ex)
{
throw new SocketException((int)ex.ErrorCode);
}
}
private void SocketEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
ProcessConnectCompleted(e);
break;
case SocketAsyncOperation.Receive:
ProcessReceiveCompleted(e);
break;
case SocketAsyncOperation.Send:
ProcessSendCompleted(e);
break;
default:
throw new Exception("Invalid operation completed");
}
}
private void ProcessConnectCompleted(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
byte[] buffer = Encoding.UTF8.GetBytes(request.ToJson() + "\n\r");
e.SetBuffer(buffer, 0, buffer.Length);
Socket sock = e.UserToken as Socket;
sock.SendAsync(e);
}
}
private void ProcessSendCompleted(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Socket sock = e.UserToken as Socket;
sock.ReceiveAsync(e);
}
}
private void ProcessReceiveCompleted(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
Socket sock = e.UserToken as Socket;
sock.Shutdown(SocketShutdown.Send);
sock.Close();
method.DynamicInvoke(dataFromServer);
}
}
}
如何从服务器获取长消息?为了让客户端尝试读取更多数据以查看我是否真的阅读了整个消息,我需要更改什么?因为这条线可能有问题:string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
它只接收消息的一部分而不是整个消息。