C# tcp服务器在第一次循环后失败
如上所述,我正在尝试用c创建一个tcp linux服务器来接受数据,执行一些处理,然后将其发送回 我试图在客户端使用的代码用于发送数据,然后将其读回:C# tcp服务器在第一次循环后失败,c#,c,sockets,tcp,tcpclient,C#,C,Sockets,Tcp,Tcpclient,如上所述,我正在尝试用c创建一个tcp linux服务器来接受数据,执行一些处理,然后将其发送回 我试图在客户端使用的代码用于发送数据,然后将其读回: TcpClient tcpclnt = new TcpClient(); tcpclnt.Connect("192.168.0.14", 1235); NetworkStream stm = tcpclnt.GetStream(); _signal.WaitOne();
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect("192.168.0.14", 1235);
NetworkStream stm = tcpclnt.GetStream();
_signal.WaitOne();
Image<Bgr, Byte> frame = null;
while (_queue.TryDequeue(out frame))
{
if (frame != null)
{
resizedBMPFrame = frame.Resize(0.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR).ToBitmap();
using (MemoryStream ms = new MemoryStream())
{
resizedBMPFrame.Save(ms, ImageFormat.Bmp);
byte[] byteFrame = ms.ToArray();
l = byteFrame.Length;
byte[] buf = Encoding.UTF8.GetBytes(l.ToString());
stm.Write(buf, 0, buf.Length);
stm.Write(byteFrame, 0, byteFrame.Length);
}
}
else
{
Reading = false;
}
int i;
Bitmap receivedBMPFrame;
byte[] receivedFramesize = new byte[4];
int j = stm.Read(receivedFramesize, 0, receivedFramesize.Length);
int receivedFramesizeint = BitConverter.ToInt32(receivedFramesize, 0);
byte[] receivedFrame = new byte[receivedFramesizeint];
j = stm.Read(receivedFrame, 0, receivedFrame.Length);
using (MemoryStream ms = new MemoryStream(receivedFrame))
{
receivedBMPFrame = new Bitmap(ms);
if (receivedBMPFrame != null)
{
outputVideoPlayer.Image = receivedBMPFrame;
}
else
{
Reading = false;
}
}
}
}
stm.Close();
tcpclnt.Close();
没有数字,这对我来说是有意义的,因为我没有发送下一帧长度的另一封信。我只是想知道我错过了什么/为什么会这样?与第一个循环一样,它会等待来自客户端的写入命令。我想知道这是否意味着写流中有剩余的数据,所以当它返回到顶部时,它会立即再次读取它?虽然它不会打印任何形式的数字,但对我来说,这意味着那里什么都没有
任何帮助都将不胜感激
编辑/更新:
将服务器上的读/写部分更改为每次执行一个字节,如下所示:
while (ntotal != incomingframesize)
{
n = read(conn_desc, &framebuff[ntotal], sizeof(char));
ntotal = ntotal + n;
while (i < k)
{
m = write(conn_desc, &framebuff[i], sizeof(char));
while(ntotal!=incomingframesize)
{
n=读取(conn_desc,&framebuff[ntotal],sizeof(char));
ntotal=ntotal+n;
而(i
这似乎解决了我遇到的问题,现在正在传输正确的数据:)当客户端写入帧大小时,它使用某个对象的长度,但当服务器读取时,它总是尝试读取6个字符。您需要为帧大小使用固定长度 在读取时,您不能假设获得的字节数与要求的字节数相同。返回值(如果>0)是实际读取的字节数。如果获得的字节数小于要求的字节数,则需要继续读取,直到收到预期的字节数为止 首先读取,直到得到6个字节(帧大小) 下次读取,直到获得帧大小指示的字节数 确保在所有位置对帧大小使用相同的字节数 编辑: 我还注意到在服务器中调用
write
时出现了一个bug:
n = write(conn_desc, &framebuff, sizeof(char)*k);
framebuff
是指向数据的指针,因此您可能的意思是:
n = write(conn_desc, &framebuff[0], k);
当您在'n=read(conn_desc,framesizebuff,6)上放置调试器断点时第二次点击这里检查“framebuff”,它是否包含一个表示数据长度的有效以null结尾的字符串?我现在将它设置为6,因为我知道发送的值是179766,通过我的客户机代码我可以看到buf。长度是6。但一般来说,你是说我需要将我的read语句包含在循环中以使确实我读的是正确的数量?我猜我误解了read命令,我以为它会一直读到我得到那么多字节?Edit:刚刚在服务器上的第二个read语句中检查了一些东西,n等于5840,这显然不是我想要的,但我不明白为什么?@geogestorm听着,你有一个带有cl的行为不正常的系统客户端和服务器。哪一端有故障?可能两者都有?将问题减少一半-使用Wireshark来找出真正发送给什么的是什么。好吧,我接受了Klas的建议,并实现了一个循环,以确保读取的字节数正确(我显然事先没有这样做!)这似乎工作正常,但在发送回数据时,数组与我发送到服务器的数组不同。receivedFrame数组中只有0个,因此我猜问题出在服务器端,我将研究使用wireshark尝试查看发送的数据。您收到n个字节,但发送回k:(我已经编辑了我的代码,所以我在服务器上的原始读取是检查n=6,我有一个while循环,直到它被读取到正确的数据量(ntotal)。我尝试将k更改为ntotal,然后发送相同的数据。只有一堆0,也通过wireshark检查,正确的数据由客户端发送,但不是从服务器返回:/
n = write(conn_desc, &framebuff, sizeof(char)*k);
n = write(conn_desc, &framebuff[0], k);