Code Bye

socket编程服务端接收客户端socket传入的数据

 

   while (true)
                {
                    try
                    {
                        
                        //通过clientSocket接收数据
                        int reciverNumber;
                        Console.WriteLine(“接收客户端:{0}消息:”, m_ClientSocket.RemoteEndPoint.ToString());
                        while ((reciverNumber = m_ClientSocket.Receive(m_DataBuffer)) != 0)
                        {
                            Console.Write(Encoding.UTF8.GetString(m_DataBuffer, 0, reciverNumber));
                        }
                        Console.WriteLine(“hello”);
                        
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        m_ClientSocket.Shutdown(SocketShutdown.Both);
                        m_ClientSocket.Close();
                        ClientsList.Remove(m_ClientSocket);
                        break;
                    }
                }
如下代码,背景是服务端接收客户端socket传入的数据。执行完while ((reciverNumber = m_ClientSocket.Receive(m_DataBuffer)) != 0)后为什么不执行     Console.WriteLine(“hello”); 我断点获取字节数组是成功的,最后也没有报catch的错。为何不向下执行hello了


40分
可能你没有仔细看MSDN
while ((reciverNumber = m_ClientSocket.Receive(m_DataBuffer)) != 0)
用的同步方式读取,直接收到数据并放入缓冲区或者发送方断开连接才会返回,并不是你想的没有数据就马上返回零
备注中有这样一段话:
如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。如果您处于非阻止模式,并且协议堆栈缓冲区中没有可用的数据,则 Receive 方法将立即完成并引发 SocketException。您可以使用 Available 属性确定是否有数据可以读取。如果 Available 为非零,请重试接收操作。
a href=”http://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.80).aspx” target=”_blank”>http://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.80).aspx
Available也只是缓冲区中有可用数据,读取后变成0也不能从根本上代表数据就接收完毕了。需要收发双方协定数据传输完毕,比如:把数据总长度放在首字节,或者在消息末了发送一个特殊的结束消息
帧是否传输完毕,Socket不会自己判断,只要连接不断,它会一致接收,直到把你的m_DataBuffer填充满为止。
引用 1 楼 dongxinxi 的回复:

可能你没有仔细看MSDN
while ((reciverNumber = m_ClientSocket.Receive(m_DataBuffer)) != 0)
用的同步方式读取,直接收到数据并放入缓冲区或者发送方断开连接才会返回,并不是你想的没有数据就马上返回零
备注中有这样一段话:
如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。如果您处于非阻止模式,并且协议堆栈缓冲区中没有可用的数据,则 Receive 方法将立即完成并引发 SocketException。您可以使用 Available 属性确定是否有数据可以读取。如果 Available 为非零,请重试接收操作。
a href=”http://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.80).aspx” target=”_blank”>http://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.80).aspx
Available也只是缓冲区中有可用数据,读取后变成0也不能从根本上代表数据就接收完毕了。需要收发双方协定数据传输完毕,比如:把数据总长度放在首字节,或者在消息末了发送一个特殊的结束消息

我开始也是觉得是报异常才没执行try最后的hello,但是问题是它根本没catch出这个SocketException,而是直接结束了这次循环。如果它执行了catch我也不上论坛问了。。。

既然你在while里输出了
Console.Write(Encoding.UTF8.GetString(m_DataBuffer, 0, reciverNumber));
那你执行过程中到底什么现象,是不断的有数据在print,还是数据早就没有了,但是程序什么反应都没有?
总之你现在有2层while循环,你得先找到到底程序陷进哪个while里出不来了
引用 2 楼 lovelj2012 的回复:

帧是否传输完毕,Socket不会自己判断,只要连接不断,它会一致接收,直到把你的m_DataBuffer填充满为止。

我断点看过,客户端传输完或者服务器接收完 ,socket的connected就会变成false,而且根据我的经验,除非连接客户端和服务器的socket一直处于类似
while(true)
{ try
{listener.receive(m_buffer);//或者send}
catch{}
}
这样的状态,否则都会马上断开的,但是我客户端只是发送一次,没有一直while(true){ client.send(m_buffer)}
不知道我的理解正不正确

引用 4 楼 Z65443344 的回复:

既然你在while里输出了
Console.Write(Encoding.UTF8.GetString(m_DataBuffer, 0, reciverNumber));
那你执行过程中到底什么现象,是不断的有数据在print,还是数据早就没有了,但是程序什么反应都没有?
总之你现在有2层while循环,你得先找到到底程序陷进哪个while里出不来了

内层的while最终是可以完整输出客户端发来的信息的,就是没有执行while后面的hello
我弄这个hello其实主要是因为这样的,本来我用stringbuilder在内层的while里面接收数据,打算最后再输出stringbuilder,结果发现没任何显示,而在while里面一接收到马上输出就可以显示。我就知道问题出在这里,然后在while后面加一句不带任何逻辑处理的hello,结果发现不执行hello。。。然后我就无语了,注意是没有报catch的错的,我调试是单步执行,执行完while接着就跳出去了,没有转向catch

引用 5 楼 qq_14919529 的回复:
Quote: 引用 2 楼 lovelj2012 的回复:

帧是否传输完毕,Socket不会自己判断,只要连接不断,它会一致接收,直到把你的m_DataBuffer填充满为止。

我断点看过,客户端传输完或者服务器接收完 ,socket的connected就会变成false,而且根据我的经验,除非连接客户端和服务器的socket一直处于类似
while(true)
{ try
{listener.receive(m_buffer);//或者send}
catch{}
}
这样的状态,否则都会马上断开的,但是我客户端只是发送一次,没有一直while(true){ client.send(m_buffer)}
不知道我的理解正不正确

错误
除非你执行了close或者程序关闭了,否则连接并不会断开,只不过是不继续发送数据了而已

还没理解?
其实执行完while没有转向catch,但也并没有跳出while,而且是
执行到reciverNumber = m_ClientSocket.Receive(m_DataBuffer)) != 0这里阻塞住了,只要socekt检测到对方还没有断开连接,就会继续接收,如果缓冲区没有收到数据,就阻塞在这里了
从发送方断开连接到你这边检测到是有一个延迟的
发送方关闭连接要记得先shutdown,然后close

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明socket编程服务端接收客户端socket传入的数据