2016-06-21 123 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)); 
    } 
}