3

ソケットへの書き込み中にTCP/IPクライアントがハングします。close()これは、サーバーが(またはshutdown())呼び出しで受け入れられた接続を適切に閉じた場合でも発生します。この場合、書き込みはECONNRESETエラーで返されるはずだといつも思っていました。

同期出力でのハングアップを防ぐにはどうすればよいですか?むしろ、エラーが報告されないように、私は何を間違っているのwrite()でしょうか?

send()代わりに使用する必要がありますか、write()それとも互換性がありますか?

2つのスレッドを持つ別のアプリケーションでネットワークをテストしています。メインスレッドはサーバースレッドを開始し、接続を受け入れてすぐに閉じます。次に、メインスレッドは、リスニングポートに接続することにより、クライアントの動作を模倣します。

メインスレッドコード:

sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
int s = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s, (sockaddr*)(&serv_addr),  sizeof(serv_addr)) < 0) {
    close(s);
    throw runtime_error(strerror(errno));
}
listen(s,1);
start_thread(s); // posix thread accepting a connection on s is started here
//Code below imitates  TCP/IP client
struct hostent *hp;
struct sockaddr_in addr;
if((hp = gethostbyname(host.c_str())) == NULL){
    throw HErrno();
}
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
int _socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_socket < 0) {
    throw Errno();
}
assert(ENOTCONN==107);
assert(_socket>=0);
if(::connect(_socket, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1){
    throw Errno();
}

while(true) {
  const char a[] = "pattern";
  if (write( _socket, a, 7)<0) // Writes 30000 times, then hangs
     break;
}

サーバースレッドコード:

int connection = accept(s);
close(connection);

編集: 問題は私のプログラミングエラーに減少しました。スレッドの受け入れを適切に開始できなかったようです。

4

2 に答える 2

1

各 TCP 接続には、受信されたがアプリケーションに配信されていないデータを格納するための受信バッファーがあります。サーバーで read() を実行しないと、データが受信バッファーに蓄積され、ある時点でこの受信バッファーがいっぱいになり、TCP が Window=0 メッセージを送信します。

サーバー スレッド コードは次のようになります。

char a[10];
int connection = accept(s);
while(true)
    if (read( connection , a, 7)<=0)
        break;
close(connection);
于 2012-11-21T06:49:35.560 に答える
0

SIGPIPEに設定する代わりに、おそらくハンドラを設定しましたSIG_IGNか?

于 2012-11-21T13:20:27.343 に答える