1 回答

TA貢獻1846條經(jīng)驗 獲得超7個贊
關于服務器與客戶端的通信,有幾個小問題,比如不正確的變量類型和缺乏錯誤檢查。
我在我的評論前面加上了>>'條件編譯'來展示我如何用建議的改進替換了 OPs 代碼的某些部分。
警告:由于服務器不知道從客戶端接收的預期字節(jié)數(shù),因此答案不包括循環(huán),試圖檢索客戶端預期的所有字節(jié)
char buf[ RECV_BUF_SIZE +1 ]; // >> +1 for string terminator
while (1)
{
// >> the third parameter is a 'socklen_t', not an 'int'
socklen_t addrlen = sizeof(cli_addr);
int clientfd =
accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);
if (clientfd < 0)
{
perror("accept error");
}
else
{
// >>recv() returns a `ssize_t`, not an `int`
ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);
#if 0
// >>this takes WAY too long, so the connection
// >>could timeout
// print everything, character by character.
char* tmp_buf = buf;
while (n_recv--) printf("%c", *tmp_buf++);
#else
if( n_recv < 0 )
{ // then an error occurred
perror( "recv failed" );
write( clientfd,
"receive error",
sizeof( "receive error" ) );
close( clientfd );
}
else if( n_recv == 0 )
{ // then client closed connection
printf( "%s\n",
"client closed connection" );
close( clientfd );
}
else
{ // some data received from client
buf[ n_recv ] = '\0'; // terminate string
printf( "%s\n", buf );
}
#endif
printf("\n\n****************************\n\n");
#if 0
FILE* res = fdopen(clientfd, "w");
fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");
fclose(res);
shutdown(clientfd, SHUT_RDWR);
close(clientfd);
#else
ssize_t writeBytes;
if( (writeBytes =
write( clientfd,
"HTTP/1.1 200 OK\r\n\r\n",
strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )
!= strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )
{ // then incomplete write
printf( "%s\n",
"write didn't write all bytes to client" );
}
close( clientfd );
#endif
}
}
分享
編輯
跟隨關于服務器與客戶端的通信,有幾個小問題,比如不正確的變量類型和缺乏錯誤檢查。
我在我的評論前面加上了>>'條件編譯'來展示我如何用建議的改進替換了 OPs 代碼的某些部分。
警告:由于服務器不知道從客戶端接收的預期字節(jié)數(shù),因此答案不包括循環(huán),試圖檢索客戶端預期的所有字節(jié)
char buf[ RECV_BUF_SIZE +1 ]; // >> +1 for string terminator
while (1)
{
// >> the third parameter is a 'socklen_t', not an 'int'
socklen_t addrlen = sizeof(cli_addr);
int clientfd =
accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);
if (clientfd < 0)
{
perror("accept error");
}
else
{
// >>recv() returns a `ssize_t`, not an `int`
ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);
#if 0
// >>this takes WAY too long, so the connection
// >>could timeout
// print everything, character by character.
char* tmp_buf = buf;
while (n_recv--) printf("%c", *tmp_buf++);
#else
if( n_recv < 0 )
{ // then an error occurred
perror( "recv failed" );
write( clientfd,
"receive error",
sizeof( "receive error" ) );
close( clientfd );
}
else if( n_recv == 0 )
{ // then client closed connection
printf( "%s\n",
"client closed connection" );
close( clientfd );
}
else
{ // some data received from client
buf[ n_recv ] = '\0'; // terminate string
printf( "%s\n", buf );
}
#endif
printf("\n\n****************************\n\n");
#if 0
FILE* res = fdopen(clientfd, "w");
fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");
fclose(res);
shutdown(clientfd, SHUT_RDWR);
close(clientfd);
#else
ssize_t writeBytes;
if( (writeBytes =
write( clientfd,
"HTTP/1.1 200 OK\r\n\r\n",
strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )
!= strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )
{ // then incomplete write
printf( "%s\n",
"write didn't write all bytes to client" );
}
close( clientfd );
#endif
}
}
添加回答
舉報