sockets - TCP 套接字上的长连接

标签 sockets 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());
    }
}

提前致谢

最佳答案

谢谢大家的回答,我没能对此做出回应,但发现 SocketOptionName.KeepAlive 似乎已经解决了这个问题:

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

并确保套接字最后没有关闭。

关于sockets - TCP 套接字上的长连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37939407/

相关文章:

actionscript-3 - socket.readBytes 不移动指针

c++ - CAsyncSocket 和线程

java - 是否有关于使用套接字与 Google App Engine for Java 服务进行客户端/服务器连接的教程?

websocket - 德尔福10.4 : Indy TIdTCPClient Reading Data from websocket and webserver

java - 如何模拟传出的套接字连接?

c++ - 为什么我的网络 TCP/UDP 实现不起作用?

c - POSIX 套接字 : How to detect Ctrl-C sent over Telnet?

c# - 在 Unity3d 中构建 WebGL 的 HTTPS 客户端

C++ 游戏应用程序 UDP 与 TCP

c - 我怎样才能通过套接字通过互联网连接到我的 friend ?