![](/img/trans.png)
[英]NetworkStream.Read() doesn't work and throws ArgumentOutOfRangeException
[英]NetworkStream.Read doesn't work the first time called
我有一个带有服务器和客户端的简单tcp / ip聊天程序。 我第一次发送数据包时,它将它发送给客户端,但是在NetworkStream期间读取它会停止执行并且不会引发异常。 我发送的下一个数据包被完美读取和处理。 我注意到的另一个奇怪的事情是,即使我从服务器获取信息,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
{
}
}
BeginReceive
异步等待消息并填充缓冲区。 然后,您开始从套接字同步读取,覆盖过程中的第一条消息。
您应该调用EndReceive
,它返回读取的字节数,然后在尝试读取更多字节之前处理缓冲区。
我不确定这是否与问题直接相关,但是您使用的Read
方法错误。 您正在将数据读取到缓冲区中,但是假设Read
调用始终返回所需的数据量,则您实际上忽略了实际读取的数据量,因此即使可能没有完全填充缓冲区,也要解码整个缓冲区。
获取Read
调用的返回值,以便您知道实际上有多少缓冲区已被数据填充:
int len = MyNetworkStream.Read(buffer, 0, buffer.Length);
string content = Encoding.ASCII.GetString(buffer, 0, len);
您需要实现EndRecieve才能从流中获取完整的数据。 从MSDN签出以下示例:
public static void Read_Callback(IAsyncResult ar){
StateObject so = (StateObject) ar.AsyncState;
Socket s = so.workSocket;
int read = s.EndReceive(ar);
if (read > 0) {
so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0,
new AsyncCallback(Async_Send_Receive.Read_Callback), so);
}
else{
if (so.sb.Length > 1) {
//All of the data has been read, so displays it to the console
string strContent;
strContent = so.sb.ToString();
Console.WriteLine(String.Format("Read {0} byte from socket" +
"data = {1} ", strContent.Length, strContent));
}
s.Close();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.