1

私はこのリンクを参照しているクライアントサーバープログラミングを使用しており、サーバーは正常に実行されています。

  1. サーバーに継続的にデータを送信する必要があります。
  2. 各パケットを送信する前に毎回 connect() したくありません。したがって、初めてソケットを作成して最初のパケットを送信し、残りのデータは write() 関数を使用してデータをソケットに書き込みました。

しかし、私の問題は、サーバーが存在しない場合、またはイーサネットが無効になっている場合でもデータを継続的に送信しているときに、ソケットにデータを正常に書き込むことです。

一度だけソケットを作成し、サーバー障害を承知の上で継続的にデータを送信する方法はありますか?

このようにする主な理由は、サーバー側で GPRS モデムを使用しており、パケットごとに connect() 関数を呼び出すたびにモデムがハングするためです。

以下のコードを使用してソケットを作成するには

Gprs_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (Gprs_sockfd < 0)
{
  Display("ERROR opening socket");
  return 0;
}
server = gethostbyname((const char*)ip_address);
if (server == NULL)
{               
  Display("ERROR, no such host");                
  return 0;
}

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(Gprs_sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
  Display("ERROR connecting");
  return 0;
}

そして、以下のコードを使用してソケットに書き込むたびに

n = write(Gprs_sockfd,data,length);
if(n<0)
{
  Display("ERROR writing to socket");
  return 0;
}   

前もって感謝します.............

4

2 に答える 2

1

TCP は、一時的な障害を許容するように設計されています。バイト シーケンス、確認応答、および必要に応じて再送信を行います。未確認のデータはすべて、カーネル ネットワーク スタック内にバッファリングされます。私の記憶が正しければ、デフォルトは 3 回の再送信試行 (私が間違っている場合は訂正してください) であり、指数関数的なバックオフ タイムアウトが発生します。それは、数分ではないにしても、すぐに数十秒になります。

私の提案は、プロトコルにアプリケーションレベルの確認応答を設計することです。つまり、サーバーは、これまでに大量のデータを受信したことを示す短い応答を送信します。たとえば、毎秒です。クライアントが 3 秒以内にサック ACK を受信しない場合、クライアントは接続が使用できないことを認識し、接続を閉じることができます。ところで、これはノンブロッキング ソケットと や のようなポーリング関数を使用すると簡単に実行できselect(2)ますpoll(2)

編集 0:

これはここで非常に関連性があると思います- 「究極のSO_LINGERページ、または: なぜ私のtcpは信頼できないのですか?」 .

于 2013-01-10T15:05:45.643 に答える
0

Nikolaiはここでは正しいです。基本的に、アプリケーションにロジックがなくてもネットワークが停止した後もデータを転送し続けることができるため、ここで経験する動作が望ましいです。アプリケーションが指定された時間よりも長い時間停止を検出する必要がある場合は、プロトコルにハートビートを追加する必要があります。これは問題を解決するための標準的な方法です。また、ネットワークに問題がなく、受信機が動作しているが、(ソフトウェアのバグが原因で)デッドロックしている状況を検出することもできます。

ハートビートは、ニコライが述べたように単純である可能性があります。X秒ごとに小さなパケットを送信します。サーバーがN*X秒間パケットを認識できない場合、接続は切断されます。

于 2013-01-11T18:25:27.590 に答える