NetworkStream.Read 第一次调用时不起作用
我有一个带有服务器和客户端的简单 tcp/ip 聊天程序。我第一次发送数据包时,它会将其发送到客户端,但在 NetworkStream.Read 期间,它会停止执行并且不会引发异常。我发送的下一个数据包将被完美读取和处理。我注意到的另一个奇怪的事情是,即使我从服务器获取信息,MyNetworkStream.DataAvailable 也总是 false,所以我必须放置一个调试符号并跳过它。我希望我可以发布我的所有代码,但它很长,所以我将发布我读取和写入网络流的位置。
public void Listen(int byteLength)
{
var buffer = new byte[byteLength];
MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Read), buffer);
}
private void Read(IAsyncResult ar)
{
while (MySocket.Connected)
{
MyNetworkStream = new NetworkStream(MySocket);
var buffer = new byte[((byte[])ar.AsyncState).Length];
if (!MyNetworkStream.DataAvailable)
throw new Exception("Data not available");
MyNetworkStream.Read(buffer, 0, buffer.Length); <------Here it stops execution without throwing an exception
string content = Encoding.ASCII.GetString(buffer);
if(OnRead == null)
continue;
var e = new CommandEventArgs( null, content);
Control target = null;
if (OnRead.Target is Control)
target = (Control)OnRead.Target;
if (target != null && target.InvokeRequired)
target.Invoke(OnRead, this, e);
else
OnRead(this,e);
}
}
public void Write(string message)
{
try
{
var buffer = Encoding.ASCII.GetBytes(message);
MySocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, null, null);
if (OnWrite != null)
{
var target = (Control)OnWrite.Target;
if (target != null && target.InvokeRequired)
{
target.Invoke(OnWrite, this, new EventArgs());
}
else
{
OnWrite(this, new EventArgs());
}
}
}
catch
{
}
}
I have a simple tcp/ip chat program with a server and client. The first time I send a packet, it makes it to the client but during the NetworkStream.Read it stops execution and doesn't throw an exception. The next packet I send is read and processed perfectly. Another weird thing I noticed is that MyNetworkStream.DataAvailable is always false even if I get information from the server so I have to put a debug symbol and skip over it. I wish I could post all my code but it is long so I will post where I read and write to the network stream.
public void Listen(int byteLength)
{
var buffer = new byte[byteLength];
MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Read), buffer);
}
private void Read(IAsyncResult ar)
{
while (MySocket.Connected)
{
MyNetworkStream = new NetworkStream(MySocket);
var buffer = new byte[((byte[])ar.AsyncState).Length];
if (!MyNetworkStream.DataAvailable)
throw new Exception("Data not available");
MyNetworkStream.Read(buffer, 0, buffer.Length); <------Here it stops execution without throwing an exception
string content = Encoding.ASCII.GetString(buffer);
if(OnRead == null)
continue;
var e = new CommandEventArgs( null, content);
Control target = null;
if (OnRead.Target is Control)
target = (Control)OnRead.Target;
if (target != null && target.InvokeRequired)
target.Invoke(OnRead, this, e);
else
OnRead(this,e);
}
}
public void Write(string message)
{
try
{
var buffer = Encoding.ASCII.GetBytes(message);
MySocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, null, null);
if (OnWrite != null)
{
var target = (Control)OnWrite.Target;
if (target != null && target.InvokeRequired)
{
target.Invoke(OnWrite, this, new EventArgs());
}
else
{
OnWrite(this, new EventArgs());
}
}
}
catch
{
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
BeginReceive
异步等待消息并填充缓冲区。然后,您开始从套接字同步读取,覆盖进程中的第一条消息。您应该调用
EndReceive
返回读取的字节数,然后在尝试读取更多字节之前处理缓冲区。BeginReceive
asynchronously waits for a message and fills your buffer. You then start synchronously reading from the socket, overwriting the first message in the process.You should call
EndReceive
which returns the number of bytes read, then process your buffer before trying to read more bytes.我不确定它是否与问题直接相关,但您使用的
Read
方法是错误的。您正在将数据读入缓冲区,但您忽略了实际读取的数据量,假设 Read 调用始终返回您请求的数据量,因此您正在解码整个缓冲区,尽管它可能不会被完全填满。获取
Read
调用的返回值,以便您知道缓冲区实际填充了多少数据:I'm not sure if it's directly related to the problem, but you are using the
Read
method wrong. You are reading data into the buffer, but you are ignoring how much data was actually read assuming that theRead
call always returns as much data as you request, so you are decoding the entire buffer eventhough it might not be completely filled.Get the return value of the
Read
call so that you know how much of the buffer is actually filled with data:您需要实现 EndRecieve 以从流中获取完整的数据。从 MSDN 中查看以下示例:
You need to implement EndRecieve to get the complete data from the stream. Checkout the following example from MSDN :