无法重启套接字

时间:2014-08-14 09:52:11

标签: c# sockets

套接字关闭后,我似乎无法重新连接。网上有几个答案,但似乎都没有。

我有一个使用以下代码连接的程序,这个代码几乎从Microsoft的例子中解脱出来。

private  void StartClient()
{
    DateTime time = DateTime.Now;              // Use current time
    string format = "ddd-d-HH:mm-ss";
    string timeString = time.ToString(format);
    // Connect to a remote device.
    try
    {                
        if (client != null)
            Stop();

        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        var state = new StateObject { workSocket = client };

        // Connect to the remote endpoint.
        client.BeginConnect(AprsConfig.URI, AprsConfig.Port,
            new AsyncCallback(ConnectCallback), client);
        connectDone.WaitOne();

        string logInString = string.Format("user {0} pass {1} vers Web-{3} 1.0 filter {2}\r\n",
                                AprsConfig.Callsign,
                                AprsConfig.Password,
                                AprsConfig.Filter,
                                timeString);
        // Send data to the remote device.
        appendToDebugFile("Sent to server: " + logInString);

        Send(client, logInString);
        sendDone.WaitOne();

        // Receive the response from the remote device.
        Receive(client);

    }
    catch (Exception e)
    {
        // Console.WriteLine(e.ToString());
        appendToDebugFile("StartClient failed : " + e.ToString());
        if (retryCount < 10)
        { 
            appendToDebugFile("Attempt to restart again");
            retryCount++;
            restartClient
        }
    }
    retryCount=0;
}

第一次正确连接没有问题。 Receive()再次调用自己,依此类推。 我不认为这是相关的,但这里是代码

private  void Receive(Socket client)
{
    try
    {
        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = client;

        // Begin receiving the data from the remote device.
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReceiveCallback), state);
    }
    catch (Exception e)
    {
        //Console.WriteLine(e.ToString());
        appendToDebugFile("Receive failed : " + e.ToString());
    }
}

 private void ReceiveCallback(IAsyncResult ar)
 {
    try
    {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.

        var state = (StateObject)ar.AsyncState;

        if (!state.workSocket.Connected)
        {
            reStartClient("Error: state.workSocket.Connected =false - Restarting");
            return;
        }

        var client = state.workSocket;

        // Read data from the remote device.
        var bytesRead = client.EndReceive(ar);

        if (bytesRead == 0)
        {
            reStartClient("ERROR: bytes==0 - Restarting");
            return;
        }

        // quickly store the buffer
        storeBytes buff = new storeBytes(state.buffer, bytesRead);
        byteQueue.Enqueue(buff);
        string data = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
        new AsyncCallback(ReceiveCallback), state);
        // setoff the readBytes Thread
        readBytesWaitHandle.Set();
    }
    catch(IOException e)
    {
        appendToDebugFile("ReceiveCallback failed : " + e.ToString());
    }
}

我正确或错误地假设如果我读取零字节,则连接失败 我尝试关闭连接并重新开始。这是我从另一个Stackoverflow答案得到的代码。

 private void reStartClient(string reason)
 {
     appendToDebugFile(reason);
     if (client != null && client.Connected)
     {
         client.Shutdown(SocketShutdown.Both);

         client.Disconnect(true);
         if (client.Connected)
             appendToDebugFile("We're still connnected");
         else
             appendToDebugFile("We're disconnected");
         client.Close();
     }
     client = null;
     // appendToDebugFile("Waiting 10 secs");
     // System.Threading.Thread.Sleep(10000);
     StartClient();
 }

正如你所看到的,我一直在尝试延迟,但这种做法并没有奏效。

重新启动后,它通过StartClient似乎连接但在尝试发送时抛出错误。这是日志文件的一部分

  

尝试重新启动Socket连接到37.187.40.234:14580   停止13/08/2014 14:18:18我们已经断开连接发送到服务器:用户   2E0ATJ传递-1 vers Web-Wed-13-14:18-18 1.0过滤器r / 51.6 / - .8 / 2000   -q / C

     

StartClient失败:System.Net.Sockets.SocketException(0x80004005):   由于套接字是,因此不允许发送或接收数据的请求   未连接和(使用sendto在数据报套接字上发送时)   call)WebAPRS.PacketListener.Send没有提供地址(Socket   客户端,字符串数据)在c:\ Users \ Alan \ Documents \ Visual Studio中   2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第188行   c:\ Users \ Alan \ Documents \ Visual中的WebAPRS.PacketListener.StartClient()   Studio 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第64行尝试   重新启动已停止13/08/2014 14:18:18发送到服务器:用户2E0ATJ   传1-vers Web-Wed-13-14:18-18 1.0过滤器r / 51.6 / - .8 / 2000 -q / C

     

StartClient失败:System.Net.Sockets.SocketException(0x80004005):   由于套接字是,因此不允许发送或接收数据的请求   未连接和(使用sendto在数据报套接字上发送时)   call)WebAPRS.PacketListener.Send没有提供地址(Socket   客户端,字符串数据)在c:\ Users \ Alan \ Documents \ Visual Studio中   2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第188行   c:\ Users \ Alan \ Documents \ Visual中的WebAPRS.PacketListener.StartClient()   Studio 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第64行尝试   再次重启停止13/08/2014 14:18:18

希望有人可以告诉我我做错了什么。

1 个答案:

答案 0 :(得分:0)

最有可能connectDoneManualResetEvent,它在之前的连接尝试中被置于信号状态,并且从未重置过。这会导致WaitOne()无法阻止,并且代码会在建立连接之前尝试发送数据。

您可以在连接之前重置它:

// Connect to the remote endpoint.
connectDone.Reset();
client.BeginConnect(AprsConfig.URI, AprsConfig.Port, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();

如果没有其他线程监视AutoResetEvent,则可以使用connectDone