サーバー上のクライアントからデータを読み取るときに問題が発生しました。read()関数は、すべてのデータが読み取られ、私にとって望ましくないデータが増えるのを待った後、常にフリーズ(ブロック)します。
サーバープログラム:
soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
bind(soc, (struct sockaddr*) &sin, sizeof(sin));
if (listen(soc, MAX))
return;
int socc; // socket for clinet
while (1) {
if ((socc = accept(soc, (struct sockaddr *) &sin, sinlen)) < 0)
break;
while ((result = read(socc, pointer, SIZE)) > 0) {
// after the data are readed, read function will block
}
// do some stuff and write reply to client => will never done
}
クライアントプログラム:
...
soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
struct sockaddr_in socketAddr;
socketAddr.sin_family = AF_INET;
socketAddr.sin_port = htons(port);
memcpy(&(socketAddr.sin_addr), host->h_addr, host->h_length);
if (connect(soc, (sockaddr *)&socketAddr, sizeof(socketAddr)) == -1)
return;
if (write(soc, req.c_str(), strlen(req.c_str())) < 0)
return;
主な問題は、クライアントがサーバーに送信するデータの量がわからないことです。そのため、サーバーはソケットからすべてのデータを読み取る必要があり、何も表示されなくなったら、読み取りサイクルを終了します。しかし、サーバーはたとえばメッセージ全体(30バイト)を読み取り、さらに待機します(ただし、これ以上は送信されません)。クライアントがサーバーからの応答を待っているため、ソケットはまだ開いています。