【发布时间】:2016-01-26 10:13:22
【问题描述】:
根据MSDN,我有以下代码来创建与 TCP/IP StreamSockets 的客户端/服务器通信。
服务器:
public async void Start(int port)
{
try
{
//Create a StreamSocketListener to start listening for TCP connections.
StreamSocketListener socketListener = new StreamSocketListener();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += SocketListener_ConnectionReceived;
//Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
await socketListener.BindServiceNameAsync(port.ToString());
}
catch (Exception ex)
{
Debug.WriteLine("SocketServer could not start. " + ex.ToString());
}
}
private async void SocketListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
string request;
//Read line from the remote client.
using (Stream inStream = args.Socket.InputStream.AsStreamForRead())
{
using (StreamReader reader = new StreamReader(inStream))
{
request = await reader.ReadLineAsync();
}
}
// Process command and get response
SocketResponse response = ProcessRequest(request);
string responseString = JsonHelper.ToJson<SocketResponse>(response);
//Send the line back to the remote client.
using (Stream outStream = args.Socket.OutputStream.AsStreamForWrite())
{
using (StreamWriter writer = new StreamWriter(outStream))
{
await writer.WriteLineAsync(responseString);
await writer.FlushAsync();
}
}
}
catch(Exception ex)
{
Debug.WriteLine("SocketListener failed." + ex.ToString());
}
}
客户:
private async Task Start(int responseTimeout)
{
CancellationTokenSource cts = new CancellationTokenSource();
try
{
cts.CancelAfter(responseTimeout);
//Create the StreamSocket and establish a connection to the echo server.
socket = new StreamSocket();
//The server hostname that we will be establishing a connection to. We will be running the server and client locally,
//so we will use localhost as the hostname.
HostName serverHost = new HostName(hostName);
//Every protocol typically has a standard port number. For example HTTP is typically 80, FTP is 20 and 21, etc.
//For the echo server/client application we will use a random port 1337.
string serverPort = port.ToString();
await socket.ConnectAsync(serverHost, serverPort).AsTask(cts.Token);
}
catch
{
socket.Dispose();
}
}
public async Task<SocketResponse> SendCommand(SocketCommand command, int responseTimeout = 2000)
{
// Connect to socket first
await Start(responseTimeout);
//Write data to the echo server.
using (Stream streamOut = socket.OutputStream.AsStreamForWrite())
{
using (StreamWriter writer = new StreamWriter(streamOut))
{
// Serialize command to json and send
string request = JsonHelper.ToJson<SocketCommand>(command);
await writer.WriteLineAsync(request);
await writer.FlushAsync();
}
}
//Read data from the echo server.
using (Stream streamIn = socket.InputStream.AsStreamForRead())
{
using (StreamReader reader = new StreamReader(streamIn))
{
string responseString = await reader.ReadLineAsync();
return JsonHelper.FromJson<SocketResponse>(responseString);
}
}
}
我的代码遇到两个问题:
- 我必须在每次请求之前从客户端建立连接。是什么原因?
- 当我从服务器发送更大的响应(字符串为 3kb)时,客户端无限等待响应,但是服务器响应很快。此外,如果服务器关闭,客户端会读取响应。这是怎么回事?
【问题讨论】:
标签: c# sockets client-server