5

クライアントサーバーアプリケーションを作成しています。サーバーはすでに設計されており、クライアントからの接続を待機しています。クライアントセクションでは、アプリケーションの存続期間中は接続を維持したいと考えています。接続は、メインクライアントアプリケーションが閉じるか、シャットダウンするか、サーバーが閉じるときにのみ閉じます。

現在、10秒ごとにサーバーがTCP接続を閉じます。試してみました

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);

しかし、それは私にとってはうまくいきません..以下は私のコードブロックです

public TCPStreamDevice(string RemoteIPAddress, int RemotePort, string SourceIPAddress, int SourcePortNo)        
{
    mIpAddress = RemoteIPAddress;
    mPort = RemotePort;

    mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    System.Net.IPEndPoint LocalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(SourceIPAddress), SourcePortNo);

    mClient.Bind(LocalEndPoint);

    mDataReceivedCallback = new AsyncCallback(DataReceivedTCPCallback_Handler);
    mBuffer = new byte[1024];
    Description = new DeviceDescription();
}

そしてハンドラーには次のものがあります:

private void DataReceivedTCPCallback_Handler(IAsyncResult ar)
{
    try
    {
        Socket client = (Socket)ar.AsyncState;
        int bytesReceived = client.EndReceive(ar);

        if (bytesReceived > 0)
        {
            //to know transport level errors
            //EngineInterface.reponseReceived(mBuffer, false);

            ReceiveCallBackFunc(mBuffer, bytesReceived);

            client.BeginReceive(mBuffer, 0, 1024, SocketFlags.None, DataReceivedTCPCallback_Handler, client);
        }
        else
        {
            //disconnect
            /* when there is no datapacket  means no TCP connection is alive now (how can i keep Tcp alive here) */
        }
    }
}
4

3 に答える 3

1

コード内のコメント (「データパケットがない場合は、TCP 接続がないことを意味します」) は、反対側から切断 (0 バイト) パケットを受信する場所に配置されます。反対側が接続を閉じることを選択したため、その接続を維持する方法はありません。

ネットワークの問題が原因で接続が閉じられている場合は、例外が発生するか、接続が有効であるが静かであるように見えます。

キープアライブ メカニズムは常にタイムアウトと一緒に機能します。タイムアウトは「x 秒間データを受信しなかった場合、接続を閉じる」ことを強制し、キープアライブは単にダミー データ パケットを送信してタイムアウトが発生しないようにします。

プロトコルを自分で実装する (TCP/IP レベルで操作している) ことにより、相手側で既にタイムアウトが実装されている場合にのみ、キープアライブを実装する必要があります。

于 2013-08-28T13:58:15.370 に答える