code in pic 12-8 save as file 12.23.bug.c
run server
(cd ./site/content/chapter12/code; make && ./12.23.bug)
let’s figure out when server will fail, see code 12.23.client.c
/*
* 12.23.client.c - An echo client
*/
#include "csapp.h"
int main(int argc, char **argv)
{
int clientfd;
char *host, *port;
char *buf = "something to send\n";
rio_t rio;
host = "127.0.0.1";
port = "5000";
clientfd = Open_clientfd(host, port);
Rio_readinitb(&rio, clientfd);
Rio_writen(clientfd, buf, strlen(buf));
/*Close(clientfd);*/
exit(0);
}
line 20 Close(clientfd)
are commented. when server is running, open another
terminal and run ./12.23.client
, server will exit with error
Rio_readlineb error: Connection reset by peer
server can’t read EOF because client doesn’t call Close
how to fix:
just output error infomation and doesn’t exit
--- 12.23.bug.c 2021-02-25 07:26:33.302592754 +0000
+++ 12.23.c 2021-02-25 07:26:33.302592754 +0000
@@ -1,7 +1,5 @@
/*
- * 12.23.bug.c - A concurrent echo server based on select
- *
- * bug in this file
+ * 12.23.c - A concurrent echo server based on select
*/
#include "csapp.h"
@@ -105,15 +103,21 @@
/* If the descriptor is ready, echo a text line from it */
if ((connfd > 0) && (FD_ISSET(connfd, &p->ready_set))) {
p->nready--;
- if ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
+ if ((n = rio_readlineb(&rio, buf, MAXLINE)) > 0) {
byte_cnt += n; //line:conc:echoservers:beginecho
printf("Server received %d (%d total) bytes on fd %d\n",
n, byte_cnt, connfd);
Rio_writen(connfd, buf, n); //line:conc:echoservers:endecho
}
-
/* EOF detected, remove descriptor from pool */
+ else if (n == 0) {
+ Close(connfd); //line:conc:echoservers:closeconnfd
+ FD_CLR(connfd, &p->read_set); //line:conc:echoservers:beginremove
+ p->clientfd[i] = -1; //line:conc:echoservers:endremove
+ }
+ /* n == -1, it's an error */
else {
+ fprintf(stderr, "error in fd %d, close fd %d connection\n", connfd, connfd);
Close(connfd); //line:conc:echoservers:closeconnfd
FD_CLR(connfd, &p->read_set); //line:conc:echoservers:beginremove
p->clientfd[i] = -1; //line:conc:echoservers:endremove