【发布时间】:2016-08-15 14:56:07
【问题描述】:
我是异步套接字编程的新手,但我的异步函数有问题。
我正在尝试为客户端创建一个使用 Windows 窗体的聊天程序,并为服务器创建一个控制台应用程序。
这是处理我的服务器上的连接的代码:
public async void StartServer()
{
TcpListener listener = new TcpListener(_ip, _port);
listener.Start();
Console.WriteLine("Server is running on IP: {0} Port: {1}", _ip.ToString(), _port);
while (true)
{
try
{
TcpClient client = await listener.AcceptTcpClientAsync();
HandleConnections(client);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
private async void HandleConnections(TcpClient client)
{
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[256];
string message = null;
int x;
while(stream.DataAvailable)
{
x = await stream.ReadAsync(buffer, 0, buffer.Length);
message += Encoding.ASCII.GetString(buffer);
}
message = message.Replace('\0', ' ');
message = message.Trim();
Console.WriteLine("Message Recieved: " + message);
byte[] bytes = Encoding.ASCII.GetBytes(message);
await stream.WriteAsync(bytes, 0, bytes.Length);
stream.Close();
}
这是客户端程序连接到服务器的代码:
private async void ConnectButton_Click(object sender, EventArgs e)
{
IPAddress address = IPAddress.Parse(IPInput.Text);
client = new TcpClient();
await client.ConnectAsync(address, 12345);
NetworkStream stream = client.GetStream();
string message = UsernameInput.Text + " Connected!";
Task<int> sendTask = SendMessage(stream, message);
int sendComp = await sendTask;
Task<string> recieveTask = RecieveMessage(stream);
string recieved = await recieveTask;
stream.Close();
ChatText.AppendText(recieved);
}
private async Task<int> SendMessage(NetworkStream stream, string message)
{
byte[] bytes = Encoding.ASCII.GetBytes(message + "\r\n");
await stream.WriteAsync(bytes, 0, bytes.Length);
return 1;
}
private async Task<string> RecieveMessage(NetworkStream stream)
{
byte[] buffer = new byte[256];
string message = null;
int x;
while (stream.DataAvailable)
{
x = await stream.ReadAsync(buffer, 0, buffer.Length);
message += Encoding.ASCII.GetString(buffer);
}
return message;
}
我遇到的第一个问题是当我运行客户端程序并单击连接按钮时,消息被发送到输出Message Recieved: user Connected! 的服务器程序,但随后客户端程序在@ 行遇到空引用异常987654324@ 表示recieved 变量为空。似乎string recieved = await recieveTask; 行并没有等待任务完成执行,而是在没有为recieved 赋值的情况下跳转到下一行。如果我在private async Task<string> RecieveMessage(NetworkStream stream) 函数的顶部放置一个断点并单步执行它,那么recieved 变量将获得它的值并且代码将成功完成,但没有断点我会得到空引用异常。
我遇到的下一个问题是,如果我让服务器保持运行并再次打开客户端并尝试连接,服务器会在 message = message.Replace('\0', ' '); 行上获得一个空引用异常。第一次用客户端运行,服务端成功接收到消息,但第二次没有从流中获取任何数据,将变量留空,导致空引用异常。
如果我的代码是垃圾,我深表歉意,我已经阅读 MSDN 文档好几个小时了,无法提出解决方案,我觉得我这样做完全错了。所以我的问题如下:
是什么导致我遇到这些错误?我是否以正确的方式解决这个问题?
【问题讨论】:
标签: c# .net async-await tcpclient tcplistener