tcp (同步)服务端 为什么会接收不到数据?
客户端发送无异常,重启程序后就可以了

解决方案 »

  1.   


    Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    Socket client;
    private void SocketReceivedata()
            {
               int port = 8888;
               string recvdata = string.Empty;//接受的数据
                string senddata = string.Empty;//发送数据
                string ipstr = string.Empty;
              byte[] data = new byte[20 * 1024];//用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组            int recv;//用于表示客户端发送的信息长度
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);//本机预使用的IP和端口
                
                newsock.Bind(ipep);//绑定
                newsock.Listen(10);//监听
                try
                {
                    while (true)
                    {
                        //用死循环来不断的从客户端获取信息
                        //data=new byte[20*1024];
                        client = newsock.Accept();
                        IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
                        if (client.Connected)
                        {
                            while (true)
                            {
                                byte[] sdata = new byte[10 * 1024];
                                recv = client.Receive(data);                            if (recv == 0)//当信息长度为0,说明客户端连接断开
                                    break;
                                recvdata = Encoding.UTF8.GetString(data, 0, recv);
                                senddata = "ok";                            sdata = Encoding.UTF8.GetBytes(senddata);
                                client.Send(sdata, sdata.Length, SocketFlags.None);
                               
                                Writetext(recvdata, clientip.Address.ToString());
                            }
                        }
                    }
                }
                catch (SocketException)
                {
                    return;
                }
            }
      

  2.   

    我记得我是在书上看到的,没有实际试过。
    调试这种程序最好是客户端服务器分别在2台pc机上。
     if (recv == 0)//当信息长度为0,说明客户端连接断开
      break;
    如果两者都在一台机子上客户端断开连接貌似recv 不会等于0.
    所以不会跳出循环。
    LZ可以试一下,然后说一下结论。我也想知道书上说的对不对。
      

  3.   

    if (client.Connected)
    这句你能断定为真吗
    如果不为真,那么你怎么可能接受到数据呢
      

  4.   

    这是CSDN上看到的,希望对楼主有所帮助Socket的Send,Recv的长度问题:一个包没有固定长度,以太网限制在46-1500字节,1500就是以太网的MTU,超过这个量,TCP会为IP数据报设置偏移量进行分片传输,现在一般可允许应用层设置8k(NTFS系统)的缓冲区,8k的数据由底层分片,而应用层看来只是一次发送。
      windows的缓冲区经验值是4k。
      Socket本身分为两种,流(TCP)和数据报(UDP),你的问题针对这两种不同使用而结论不一样。甚至还和你是用阻塞、还是非阻塞Socket来编程有关。
      1、通信长度,这个是你自己决定的,没有系统强迫你要发多大的包,实际应该根据需求和网络状况来决定。对于TCP,这个长度可以大点,但要知道,Socket内部默认的收发缓冲区大小大概是8K,你可以用SetSockOpt来改变。但对于UDP,就不要太大,一般在1024至10K。注意一点,你无论发多大的包,IP层和链路层都会把你的包进行分片发送,一般局域网就是1500左右,广域网就只有几十字节。分片后的包将经过不同的路由到达接收方,对于UDP而言,要是其中一个分片丢失,那么接收方的IP层将把整个发送包丢弃,这就形成丢包。显然,要是一个UDP发包佷大,它被分片后,链路层丢失分片的几率就佷大,你这个UDP包,就佷容易丢失,但是太小又影响效率。最好可以配置这个值,以根据不同的环境来调整到最佳状态。
      send()函数返回了实际发送的长度,在网络不断的情况下,它绝不会返回(发送失败的)错误,最多就是返回0。对于TCP你可以写一个循环发送。当 send函数返回SOCKET_ERROR时,才标志着有错误。但对于UDP,你不要写循环发送,否则将给你的接收带来极大的麻烦。所以UDP需要用 SetSockOpt来改变Socket内部Buffer的大小,以能容纳你的发包。明确一点,TCP作为流,发包是不会整包到达的,而是源源不断的到,那接收方就必须组包。而UDP作为消息或数据报,它一定是整包到达接收方。
      2、关于接收,一般的发包都有包边界,首要的就是你这个包的长度要让接收方知道,于是就有个包头信息,对于TCP,接收方先收这个包头信息,然后再收包数据。一次收齐整个包也可以,可要对结果是否收齐进行验证。这也就完成了组包过程。UDP,那你只能整包接收了。要是你提供的接收Buffer过小,TCP 将返回实际接收的长度,余下的还可以收,而UDP不同的是,余下的数据被丢弃并返回WSAEMSGSIZE错误。注意TCP,要是你提供的Buffer佷大,那么可能收到的就是多个发包,你必须分离它们,还有就是当Buffer太小,而一次收不完Socket内部的数据,那么Socket接收事件 (OnReceive),可能不会再触发,使用事件方式进行接收时,密切注意这点。这些特性就是体现了流和数据包的区别。
      补充一点,接收BuffSize >= 发送BuffSize >= 实际发送Size,对于内外部的Buffer都适用,上面讲的主要是Socket内部的Buffer大小关系。
      3、TCP是有多少就收多少,如果没有当然阻塞Socket的recv就会等,直到有数据,非阻塞Socket不好等,而是返回 WSAEWOULDBLOCK。UDP,如果没有数据,阻塞Socket就会等,非阻塞Socket也返回WSAEWOULDBLOCK。如果有数据,它是会等整个发包到齐,并接收到整个发包,才返回。
      

  5.   

    [color=#FF6600我现在的问题是这样
    我只做服务端,对方是客户端
    出现问题:
    1.有时候接收不到数据,可对方发送数据正常,会是什么问题?
    2.对方客户端接收数据有重复(收到两条记录,且第一调记录有点乱),是服务端问题呢,还是客户端问题?还有就是 总感觉上面的代码有问题 可就不知道如何改[/color]
      

  6.   

    对方发送数据正常???
    接受不到有可能是客户端发送失败也有可能服务器端发送失败
    还有tcp是要三握手的你服务器端要返回客户端信息,否则 客户端过些时候接受不到服务器端的信息,连接 就会失效。
    按你现在的状态感觉应该是客户端的问题。而不是服务器端的问题。
      

  7.   


    如果对方一下子发送10241个字节怎么办?另外所谓的“沾包”是很正常的,你的一次receive里可能有对方两个发送的消息,甚至更多次的消息;甚至buffer的开始不是一个消息的开头,因为上一次Receive没有穷见所有数据(即使对方法的消息很小,但是还有算上沾包的),此时消息内容就跨前后两次Receive的边界里边。
      

  8.   

    找一个真正做过产品的人面对面实际去问问吧。这种东西,不是从网上抄点文章,就能做起来的。网上的文章可以执行,但是往往执行它的人都找个借口:“嗯,如果消息发送快了,或者内容大了,我还不行。但是小的我已经行了!”。其实产品代码根本不是弄一个winform程序对另外一个winform程序发点demo数据的网上程序那样写的。
      

  9.   

    TCP 是基于流的协议。。所以需要自行定义封包格式。最简单的是发送的时候在封包头部加上长度,读取是根据长度截取。就不会出现丢信息的现象。再者 TCP 是面向连接的协议,所以出现的一切数据读取问题都是程序问题不可能是网络问题。不过。。好多写出非常烂的网络发送程序的人,都拒绝承认这个事实