我们在做一个c#的socket通信的程序,但是非常诡异的就是,我们用vs在调试环境下是100%可以运行的,但是直接双击.exe文件居然10次里有9次会报socket error,还有1次能成功运行。
巨大的bug但是查不出原因哦急待高手相救,谢谢。

解决方案 »

  1.   

    捕获的异常如下:
    无法将数据写入传输连接,由于嵌套字没有连接(当使用一个 sendto 调用发送数据报嵌套字时)没有提供地址,发送或接收数据的请求没有被接受。。问题是在调试模式下是不会出这个错误的,怎么连都是ok的
      

  2.   

    贴个代码撒   有些错误在Debug下都能过
      

  3.   

    socket连接的时候 需要3次握手 需要提供IP地址和端口号。。
      

  4.   

    正常,你在调试环境下运行的时候比你执行exe要长,所以仍然有部分的错误你调试是没有办法重现的。感觉你的这个错误是因为异步原因导致的,虽然我不知道你的程序里是否用到了异步的方式。而根据你捕捉的异常来看,肯定是你的socket在send的时候,发现目标socket已经断开链接了,好好检查你的逻辑,看看是否服务端或者客户端在进行一次通讯之后就马上断开了(如果你不希望他断开的话)。
      

  5.   

    是不是端口还未释放啊。。你在命令行中用netstat -a -n看一下你的程序使用的端口。。
      

  6.   

    ...端口(port)有没有被占用?有时候,程式是关闭了,但是查看任务管理器里的线程却没有关闭,此时端口被占用,会出现Socket Error,楼主试试看看
      

  7.   

    哦,在下工作也是C#网路通信类,楼主有兴趣就私下交流下,QQ251758448
      

  8.   


     IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 10000);
            private void Listen()
            {
                // Create a TCP/IP socket.
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // Bind the socket to the local endpoint and listen for incoming connections.
                try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(100);
                    listener.ReceiveTimeout = 50000;
                    m_Listening = true;                while (m_Listening)
                    {
                        // Set the event to nonsignaled state.
                        allDone.Reset();                    // Start an asynchronous socket to listen for connections.
                        Console.WriteLine("Waiting for a connection...");
                        listener.BeginAccept(new AsyncCallback(AcceptCallback), null);                    // Wait until a connection is made before continuing.
                        allDone.WaitOne();
                    }            }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    ErrorPrinter.PrintLog(ex);
                }        }        public void AcceptCallback(IAsyncResult ar)
            {
                // Signal the main thread to continue.
                allDone.Set();
                // Get the socket that handles the client request.
                Socket newSock = listener.EndAccept(ar);            agsXMPP.XmppServerConnection con = new agsXMPP.XmppServerConnection(this,newSock);
            }
    以上是客户端的代码,我们是一个即时通讯的系统,如果各位需要其他信息的话请加我qq:87373176,我可以把相关程序发给大家的。谢谢
      

  9.   

    然后xmppServerConnection里做了这些事:                m_Sock.ReceiveTimeout = 50000;
                    m_Sock.SendTimeout = 50000;
                    m_Sock.BeginReceive(buffer, 0, BUFFERSIZE, 0, new AsyncCallback(ReadCallback), null);
              
    public void ReadCallback(IAsyncResult ar) 
    {
                try
                {
                    int bytesRead = m_Sock.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        streamParser.Push(buffer, 0, bytesRead);
                        m_Sock.BeginReceive(buffer, 0, BUFFERSIZE, 0, new AsyncCallback(ReadCallback), null);
                    }
                    else
                    {
                        m_Sock.Shutdown(SocketShutdown.Both);
                        m_Sock.Close();
                    }
                }
                catch
                {
                    Console.WriteLine("read call back error");  //这里需要观察下,暂时不输出
                    deluser();
                }
    }
      

  10.   

    总觉得你这里有问题
    if (bytesRead > 0)
    {
        streamParser.Push(buffer, 0, bytesRead);
        m_Sock.BeginReceive(buffer, 0, BUFFERSIZE, 0, new AsyncCallback(ReadCallback), null);
    }
    else
    {
        m_Sock.Shutdown(SocketShutdown.Both);
        m_Sock.Close();
    }bytesRead 是 BeginReceive 的返回值,MSDN中的解释是如果远程主机使用 Shutdown 方法关闭了 Socket 连接,并且所有可用数据均已收到,则 EndReceive 方法将立即完成并返回零字节。在我自己使用receive的时候,我不会在 bytesRead > 0 的时候始终进行BeginReceive的调用。
    是这样的,如果对方发送数据之后,马上就关闭链接,那么你的 bytesRead 这个时候的值还是 > 0的(如果最后一次传输是有数据的话),你想一想,如果这个时候你仍然去receive,肯定报错啊。目前我使用的方法还是跟MSDN上一样,至少我没有报过这样的错,做法是在对方发送的结尾加个标识,在你接收的时候,你就判断到目前为止接收到的数据是否是以这个标识结尾,如果是,那么你就可以处理了,如果不是那么你就继续receive。其实我个人认为想要得到 bytesRead = 0的情况还真不适用与你目前的短链接架构,bytesRead = 0可以在长链接中用于判断是否接收完毕,因为对方发送完毕之后不会马上就断开链接,你即便使用receive也不会报错,因为对方还在链接。但是看你的代码,你的框架似乎是个短链接,发送完毕就关闭,需要再链接,如果是这样的话,你就不要用bytesRead = 0来判断是否发送完毕了,而你应该在bytesRead 》 0中就应该判断对方是否发送完毕了
      

  11.   

    多谢各位,这个问题终于解决了
    Lovely_baby说的很对,线程太多了大概总结下哈其实是这样的,con.open里面有新建线程,con.open的这个办法和ui放同一个线程就ok了,不需要单独再建的。
    我把ui的线程阻塞掉,open马上就顺利执行了,后来看代码才发现ui里是新建线程做open这个事情的。
    总结了一个规律啊,绝对不能用没有代码的dll,一定要把代码附加上去一点点往里看啊。
    另外vs跑和实际运行的有可能时间片不一样,在多线程的情况下很有可能有差别的。