2016-06-21 100 views
1

您可以請協助。根據製造商的說法,我正在與需要長連接選項的設備進行集成。你有什麼想法如何做到這一點?TCP插座上的長連接

這是我迄今在大多數情況下工作的代碼:

public AsynchronousSocketListener(IPEndPoint endPoint, ILog log) 
{ 
    _EndPoint = endPoint; 
    _log = log; 
    Console.WriteLine(String.Format("Started: {0}:{1}", endPoint.Address, endPoint.Port)); 
} 

public void StartListening() 
{ 
    // Data buffer for incoming data. 
    byte[] bytes = new Byte[1024]; 

    // Create a TCP/IP socket. 
    Socket socket = new Socket(AddressFamily.InterNetwork, 
    SocketType.Stream, ProtocolType.Tcp); 
    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 

    // Bind the socket to the local endpoint and listen for incoming connections. 
    try 
    { 

     socket.Bind(_EndPoint); 
     socket.Listen(100000); 
     Console.WriteLine("Listen"); 

     while (true) 
     { 
      // Set the event to nonsignaled state. 
      allDone.Reset(); 

      // Start an asynchronous socket to listen for connections. 
      socket.BeginAccept(
        new AsyncCallback(AcceptCallback), 
        socket); 

      // Wait until a connection is made before continuing. 
      allDone.WaitOne(); 
     } 

    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(String.Format("Error:{0}", ex.Message)); 
    } 
} 


public void AcceptCallback(IAsyncResult ar) 
{ 
    // Signal the main thread to continue. 
    allDone.Set(); 

    // Get the socket that handles the client request. 
    Socket listener = (Socket)ar.AsyncState; 
    Socket handler = listener.EndAccept(ar); 

    // Create the state object. 
    StateObject state = new StateObject(); 
    state.workSocket = handler; 
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
     new AsyncCallback(ReadCallback), state); 
} 

public void ReadCallback(IAsyncResult ar) 
{ 
    String content = String.Empty; 

    // Retrieve the state object and the handler socket 
    // from the asynchronous state object. 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket handler = state.workSocket; 

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar); 

    if (bytesRead > 0) 
    { 
     // There might be more data, so store the data received so far. 
     state.sb.Append(Encoding.ASCII.GetString(
      state.buffer, 0, bytesRead)); 

     // Check for end-of-file tag. If it is not there, read 
     // more data. 
     content = state.sb.ToString(); 
     Console.WriteLine(String.Format("RECEIVED: {0}", content)); 
     if (content.IndexOf("\u0001") > -1) 
     { 
      string imei = string.Empty; 
      foreach (string response in ResponseHandler.GetRequestResponse(content, out imei)) 
      { 
       Send(handler, response, imei); 
       Console.WriteLine(String.Format("RESPONSE: {0}", response)); 
      } 
     } 
     else 
     { 
      // Not all data received. Get more. 
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
      new AsyncCallback(ReadCallback), state); 
     } 
    } 
} 

private void Send(Socket handler, String data, string imei) 
{ 
    // Convert the string data to byte data using ASCII encoding. 
    byte[] byteData = Encoding.ASCII.GetBytes(data); 
    //Terminator 
    byte[] terminator = new byte[3] { 0x01, 0x01, 0x01 }; 
    //Create new array with added 3 spaces for terminator 
    byte[] terminalResponse = new byte[byteData.Length + 3]; 
    //Copy command byte array to new array 
    byteData.CopyTo(terminalResponse, 0); 
    //Copy terminator byte array to new array 
    terminator.CopyTo(terminalResponse, terminalResponse.Length - 3); 

    // Begin sending the data to the remote device. 
    handler.BeginSend(terminalResponse, 0, terminalResponse.Length, 0, 
     new AsyncCallback(SendCallback), handler); 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     // Retrieve the socket from the state object. 
     Socket handler = (Socket)ar.AsyncState; 

     // Complete sending the data to the remote device. 
     int bytesSent = handler.EndSend(ar); 

     //handler.Shutdown(SocketShutdown.Both); 
     //handler.Close(); 

    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

在此先感謝

+1

如果「作品在大多數情況下」,那麼究竟是什麼問題,你有? – selbie

+1

什麼是「長連接」選項? – freakish

+0

對於某些電話,我只是沒有收到數據和製造商的幫助通知我我沒有申請長連接選項。難住了。我想也許這是在SocketOptions上的一些選項,但我很新的TCP服務器代碼編寫的東西:) –

回答

0

感謝您的答案的傢伙,我沒有對這個迴應,卻發現SocketOptionName .KeepAlive似乎解決了這個問題:

// Create a TCP/IP socket. 
Socket socket = new Socket(AddressFamily.InterNetwork, 
SocketType.Stream, ProtocolType.Tcp); 
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 

並確保套接字未在最後關閉。

+0

如果這是製造商的意思,他應該這麼說,你應該向他抱怨說他沒有。 – EJP

+0

感謝您的幫助EJP,遺憾的是與普通話有一點溝通。 –

-1

這可能有助於某人,或者如果你能看到如何改善這一點,請讓我知道。但這裏是我的版本現在使用:

public async Task StartListening() 
{ 
    // Data buffer for incoming data. 
    byte[] bytes = new Byte[1024]; 

    // Create a TCP/IP socket. 
    Socket socket = new Socket(AddressFamily.InterNetwork, 
    SocketType.Stream, ProtocolType.Tcp); 
    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 

    // Bind the socket to the local endpoint and listen for incoming connections. 
    try 
    { 
     socket.Bind(_EndPoint); 
     socket.Listen(100000); 
     Console.WriteLine(String.Format("Socket connected to {0}", _EndPoint.Address)); 

     while (true) 
     { 
      // Program is suspended while waiting for an incoming connection. 
      Socket handler = socket.Accept(); 
      data = null; 

      // An incoming connection needs to be processed. 
      while (true) 
      { 
       bytes = new byte[1024]; 
       int bytesRec = handler.Receive(bytes); 
       data += Encoding.ASCII.GetString(bytes, 0, bytesRec); 
       if (data.IndexOf("\u0001") > -1) 
       { 
        break; 
       } 
      } 

      Console.WriteLine(String.Format("RECEIVED: {0}", data)); 

      // Echo the data back to the client. 
      byte[] msg = Encoding.ASCII.GetBytes(data); 

      handler.Send(msg); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(String.Format("Error:{0}", ex.Message)); 
    } 
}