Reputation: 1
I met a strange problem when I test my server and client. The server and client appear TIME_WAIT at the same time!
Here is my server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h> //bzero
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define LISTEN_QUEUE 20
#define MAX_LINE 1024
#define MAXN 16384
int parse(char *buf)
{
int num;
sscanf(buf, "%d", &num);
return num;
}
int main()
{
int listenfd, connfd, r, n;
pid_t childpid;
socklen_t chilen;
struct sockaddr_in chiaddr, servaddr;
char buf[MAX_LINE];
char content[MAXN];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0)
printf("listen socket get error\n"), exit(-1);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999);
r = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if(r < 0)
printf("bind socket error\n"), exit(-1);
r = listen(listenfd, LISTEN_QUEUE);
memset(content, 'A', MAXN);
while(1)
{
chilen = sizeof(chiaddr);
connfd = accept(listenfd, (struct sockaddr *)&chiaddr, &chilen);
memset(buf, 0, MAX_LINE);
r = read(connfd, buf, MAX_LINE);
n = parse(buf);
write(connfd, content, n);
close(connfd);
}
}
And here is my client code:
#include <unp.h>
#define MAXN 16384
static int readn(int fd, char *buf, int nbytes)
{
int nread, ntoread, n;
#ifdef __DEBUG__
char temp[1024];
#endif /* __DEBUG__ */
nread = 0;
ntoread = nbytes;
while(nread < nbytes)
{
n = read(fd, buf, ntoread);
if(n < 0)
printf("read nbytes error\n"), exit (-1);
else if(n == 0)
break;
else
{
#ifdef __DEBUG__
memcpy(temp, buf, n);
temp[n] = 0;
printf("%s\n", temp);
#endif /* _DEBUG__ */
buf += n;
nread += n;
ntoread = nbytes - nread;
}
}
return nread;
}
static int Tcp_connect(char *host, char *port)
{
struct hostent *h;
char str[16];
struct sockaddr_in addr;
h = gethostbyname(host);
addr.sin_family = h->h_addrtype;
addr.sin_port = htons(atoi(port));
addr.sin_addr = *(struct in_addr *)(h->h_addr);
#ifdef __DEBUG__
if(h->h_addrtype == AF_INET)
printf("AF_INET\n");
printf("server ip is :%s\n", inet_ntoa(addr.sin_addr));
#endif /* __DEBUG__ */
int fd = socket(h->h_addrtype, SOCK_STREAM, 0);
if(fd < 0)
printf("socket get failed\n"), exit(-1);
#ifdef __DEBUG__
printf("socket get success\n");
#endif /* __DEBUG__ */
if(connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
printf("connect failed\n"), exit(-1);
#ifdef __DEBUG__
printf("connected success\n");
#endif /* __DEBUG__ */
return fd;
}
int main(char argc, char *argv[])
{
int i, j, fd, nchilds, nloops, nbytes;
pid_t pid;
ssize_t n, nread;
char request[MAX_LINE], reply[MAXN];
if(argc != 6)
printf("usage : client <IP addr> <port> <#children>
<#loops/child> <#bytes/request>"),
exit(-1);
nchilds = atoi(argv[3]);
nloops = atoi(argv[4]);
nbytes = atoi(argv[5]);
snprintf(request, sizeof(request), "%d\n", nbytes);
for(i = 0; i < nchilds; i++)
{
if((pid = fork()) == 0) //son
{
nread = 0;
for(j = 0; j < nloops; j++)
{
// printf("begin connect\n");
fd = Tcp_connect(argv[1], argv[2]);
write(fd, request, strlen(request));
if((n = readn(fd, reply, nbytes)) != nbytes)
printf("server return %d bytes\n", (int)n), exit(-1);
else
nread += n;
close(fd);
}
printf("child %d done, read total %d bytes\n", i, (int)nread);
exit(0);
}
}
while(wait(NULL) > 0) ;
if(errno != ECHILD)
printf("wait error\n"), exit(-1);
}
I run server and client on my machine. And the client cmd is
./client 127.0.0.1 9999 5 100 4000
and then I run
netstat -a | grep 9999 > log
when I run
grep -c TIME_WAIT log
the result is 501, but according to book, the result should be 500. I open the log, then I find server and client in TIME_WAIT at the same time on one connection
tcp 0 0 localhost:54915 localhost:9999 TIME_WAIT
tcp 0 0 localhost:9999 localhost:54915 TIME_WAIT
It is so strange, I don't know why
Upvotes: 0
Views: 1263
Reputation: 631
You are establishing and closing connection between client and server in loop - client connects to server, sends some data, receives response from server and then closes the connection. Similarly the server also disconnects after this exchange. You are observing TIME_WAIT state as you are closing connections between client and server.
The TIME_WAIT state is a normal TCP connection state, as the TCP stack does not immediately wipe out the TCBs after FIN exchange. The TIME_WAIT state represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request. Please refer to TCP RFC 793 for more details on TCP state machine.
If you do a grep on port 9999, you will notice connection in ESTABLISHED state while your client and server are running.
Possibly you can avoid establishing and closing TCP connection in loop, that is, change your server and client programs to establish connection and then enter the loop for exchanging data.
Upvotes: 1