C# tcp服务器在第一次循环后失败

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();

如上所述,我正在尝试用c创建一个tcp linux服务器来接受数据,执行一些处理,然后将其发送回

我试图在客户端使用的代码用于发送数据,然后将其读回:

        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);