2016-06-21 22 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)); 
    } 
} 
関連する問題