c#Socket接收数据的问题

Y19521 2014-06-28 12:06:13
接收数据时,不知道什么原因,它老是处于接收状态,怎么判断已经接收完毕了呢,代码如下:

Socket ss=null;
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 510);
Socket serverSocket = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipep);
serverSocket.Listen(10);
ss = serverSocket.Accept();
try
{
while (true)
{
Byte[] inBuffer = new Byte[1024];
MemoryStream ms = new MemoryStream();
int a = 0;

while (true)
{
try
{
a = ss.Receive(inBuffer, 1024, SocketFlags.None);
}
catch (Exception ex)
{
string ss = ex.Message;
}
if (a == 0)
{
break;
}
else
{
ms.Write(inBuffer, 0, a);
}
}
BinaryFormatter formatter = new BinaryFormatter();
ms.Flush();
ms.Position = 0;
if (ms.Capacity > 0)
{
LoginInfo li = (LoginInfo)formatter.Deserialize(ms);
txtshow.Text += li.username+"\r\n";
}
ms.Close();
}
}
catch (Exception ex)
{
string s = ex.Message;
}



我传输的是序列化的数据,在调试中,发现程序在 a = ss.Receive(inBuffer, 1024, SocketFlags.None);这里,循环两次后停在这里了,说明程序已经接受完毕了,但是它没有退出,求解!
...全文
328 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Y19521 2014-07-09
  • 打赏
  • 举报
回复
求解啊,大婶们,
孤独de猫 2014-06-28
  • 打赏
  • 举报
回复
在帮助文档里面搜socket,然后看BeginAccept(), BeginRecive()之类的,带begin的 就是异步的, 这些函数里面就有自带的代码示例,研究下。
Y19521 2014-06-28
  • 打赏
  • 举报
回复
引用 9 楼 laizhiping_rj 的回复:
[quote=引用 7 楼 ta_wuhen 的回复:] [quote=引用 楼主 Y19521 的回复:] 接收数据时,不知道什么原因,它老是处于接收状态,怎么判断已经接收完毕了呢 [

Receive 方法将数据读入 buffer 参数,并返回成功读取的字节数。从面向连接的套接字和无连接套接字中都可以调用 Receive。 

此重载仅要求您提供接收缓冲区。缓冲区偏移量的默认值为 0,缓冲区的默认大小为缓冲区参数的长度,而 SocketFlags 的默认值为 None。 

如果您使用的是面向连接的协议,则在调用 Receive 之前,必须调用 Connect 以建立远程主机连接,或者调用 Accept 以接受传入的连接。Receive 方法只读取在 Connect 或 Accept 方法中建立的远程主机发送的数据。如果当前使用的是无连接协议,则还可以使用 ReceiveFrom 方法。ReceiveFrom 将允许您接收来自任何主机的数据。 

如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket..::.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。如果您处于非阻止模式,并且协议堆栈缓冲区中没有可用的数据,则 Receive 方法将立即完成并引发 SocketException。您可以使用 Available 属性确定是否有数据可以读取。如果 Available 为非零,请重试接收操作。 

如果当前使用的是面向连接的 Socket,那么 Receive 方法将会读取所有可用的数据,直到达到缓冲区的大小为止。如果远程主机使用 Shutdown 方法关闭了 Socket 连接,并且所有可用数据均已收到,则 Receive 方法将立即完成并返回零字节。 

如果您使用的是无连接 Socket,则 Receive 将从您在 Connect 方法中指定的目标地址处读取第一个排队的数据报。如果您接收到的数据报大于 buffer 参数的大小,则 buffer 将用消息的第一部分填充,多余的数据都会丢失,并且会引发 SocketException。 

类似于Accept(),所以最好新建个独立的线程用于接收[/quote] 对于服务端,每个socket用一个线程不靠谱, 可以用异步 SendAsync、 ReceiveAsync [/quote] 有木有实例参考一下
孤独de猫 2014-06-28
  • 打赏
  • 举报
回复
用异步通信呀
laizhiping_rj 2014-06-28
  • 打赏
  • 举报
回复
引用 7 楼 ta_wuhen 的回复:
[quote=引用 楼主 Y19521 的回复:] 接收数据时,不知道什么原因,它老是处于接收状态,怎么判断已经接收完毕了呢 [

Receive 方法将数据读入 buffer 参数,并返回成功读取的字节数。从面向连接的套接字和无连接套接字中都可以调用 Receive。 

此重载仅要求您提供接收缓冲区。缓冲区偏移量的默认值为 0,缓冲区的默认大小为缓冲区参数的长度,而 SocketFlags 的默认值为 None。 

如果您使用的是面向连接的协议,则在调用 Receive 之前,必须调用 Connect 以建立远程主机连接,或者调用 Accept 以接受传入的连接。Receive 方法只读取在 Connect 或 Accept 方法中建立的远程主机发送的数据。如果当前使用的是无连接协议,则还可以使用 ReceiveFrom 方法。ReceiveFrom 将允许您接收来自任何主机的数据。 

如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket..::.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。如果您处于非阻止模式,并且协议堆栈缓冲区中没有可用的数据,则 Receive 方法将立即完成并引发 SocketException。您可以使用 Available 属性确定是否有数据可以读取。如果 Available 为非零,请重试接收操作。 

如果当前使用的是面向连接的 Socket,那么 Receive 方法将会读取所有可用的数据,直到达到缓冲区的大小为止。如果远程主机使用 Shutdown 方法关闭了 Socket 连接,并且所有可用数据均已收到,则 Receive 方法将立即完成并返回零字节。 

如果您使用的是无连接 Socket,则 Receive 将从您在 Connect 方法中指定的目标地址处读取第一个排队的数据报。如果您接收到的数据报大于 buffer 参数的大小,则 buffer 将用消息的第一部分填充,多余的数据都会丢失,并且会引发 SocketException。 

类似于Accept(),所以最好新建个独立的线程用于接收[/quote] 对于服务端,每个socket用一个线程不靠谱, 可以用异步 SendAsync、 ReceiveAsync
我现在在路上 2014-06-28
  • 打赏
  • 举报
回复
引用 7 楼 ta_wuhen 的回复:
[quote=引用 楼主 Y19521 的回复:] 接收数据时,不知道什么原因,它老是处于接收状态,怎么判断已经接收完毕了呢 [
类似于Accept(),所以最好新建个独立的线程用于接收[/quote] 我擦,标签不能嵌套使用啊... 如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用
我现在在路上 2014-06-28
  • 打赏
  • 举报
回复
引用 楼主 Y19521 的回复:
接收数据时,不知道什么原因,它老是处于接收状态,怎么判断已经接收完毕了呢 [

Receive 方法将数据读入 buffer 参数,并返回成功读取的字节数。从面向连接的套接字和无连接套接字中都可以调用 Receive。 

此重载仅要求您提供接收缓冲区。缓冲区偏移量的默认值为 0,缓冲区的默认大小为缓冲区参数的长度,而 SocketFlags 的默认值为 None。 

如果您使用的是面向连接的协议,则在调用 Receive 之前,必须调用 Connect 以建立远程主机连接,或者调用 Accept 以接受传入的连接。Receive 方法只读取在 Connect 或 Accept 方法中建立的远程主机发送的数据。如果当前使用的是无连接协议,则还可以使用 ReceiveFrom 方法。ReceiveFrom 将允许您接收来自任何主机的数据。 

如果没有可读取的数据,则 Receive 方法将一直处于阻止状态,直到数据可用,除非使用 Socket..::.ReceiveTimeout 设置了超时值。如果超过超时值,Receive 调用将引发 SocketException。如果您处于非阻止模式,并且协议堆栈缓冲区中没有可用的数据,则 Receive 方法将立即完成并引发 SocketException。您可以使用 Available 属性确定是否有数据可以读取。如果 Available 为非零,请重试接收操作。 

如果当前使用的是面向连接的 Socket,那么 Receive 方法将会读取所有可用的数据,直到达到缓冲区的大小为止。如果远程主机使用 Shutdown 方法关闭了 Socket 连接,并且所有可用数据均已收到,则 Receive 方法将立即完成并返回零字节。 

如果您使用的是无连接 Socket,则 Receive 将从您在 Connect 方法中指定的目标地址处读取第一个排队的数据报。如果您接收到的数据报大于 buffer 参数的大小,则 buffer 将用消息的第一部分填充,多余的数据都会丢失,并且会引发 SocketException。 

类似于Accept(),所以最好新建个独立的线程用于接收
laizhiping_rj 2014-06-28
  • 打赏
  • 举报
回复


                    Socket ss=null;
                    IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 510);
                    Socket serverSocket = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    serverSocket.Bind(ipep);
                    serverSocket.Listen(10);
                    ss = serverSocket.Accept();
                    try
            {
                while (true)
                {
                    Byte[] inBuffer = new Byte[1024];
                    MemoryStream ms = new MemoryStream();
                    int a = 0;

                    if(0 < ss.Available)
                    {
                            a = ss.Receive(inBuffer, 1024, SocketFlags.None);
                            ms.Write(inBuffer, 0, a);
                    BinaryFormatter formatter = new BinaryFormatter();
                    ms.Flush();
                    ms.Position = 0;
                    if (ms.Capacity > 0)
                    {
                        LoginInfo li = (LoginInfo)formatter.Deserialize(ms);
                        txtshow.Text += li.username+"\r\n";
                    }
                    ms.Close();
                }
        else
{
Thread.Sleep(100);
}
}
            }
            catch (Exception ex)
            {
                string s = ex.Message;
            }


laizhiping_rj 2014-06-28
  • 打赏
  • 举报
回复

while(0 < ss.Available)
{
    a = ss.Receive(inBuffer, inBuffer.Length, SocketFlags.None);
}
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
感觉 是双层for循环的问题。 可以尝试修改Receive方法,
Receive(bytesReceived, bytesReceived.Length, 0);
瞎了!!!!是while循环。。。。
save4me 2014-06-28
  • 打赏
  • 举报
回复
break只能跳出当前的while,你的代码只有内层的while有break,外层while没有地方break,所以这样永远跳不出来。
  • 打赏
  • 举报
回复
感觉 是双层for循环的问题。 可以尝试修改Receive方法,
Receive(bytesReceived, bytesReceived.Length, 0);
gomoku 2014-06-28
  • 打赏
  • 举报
回复
对Tcp来说,只要连接没有断开,Receive就会保持等待(你不知道是否对方十分钟后还会发数据)。 因此,最好的解决方案就是知道对方数据的长度,从而每收到一定的数据就可进行处理。长度可以通过协议来达成,而最常见的方法就是先发数据长度,再发数据。

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧