Last active
August 29, 2015 14:22
-
-
Save likejazz/aaacad19644c2b5cb13e to your computer and use it in GitHub Desktop.
How to handle TIME_WAIT state
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <time.h> | |
#include <pthread.h> | |
#define BACKLOG 128 // backlog for listen() | |
#define DEFAULT_PORT 5000 // default listening port | |
#define BUF_SIZE 28 // message chunk size | |
time_t ticks; | |
typedef struct { | |
int client_sock; | |
} thread_param_t; | |
thread_param_t *params; // params structure for pthread | |
pthread_t thread_id; // thread id | |
void error(char *msg) { | |
perror(msg); | |
exit(EXIT_FAILURE); | |
} | |
/** | |
* thread handler after accept() | |
*/ | |
void *handle_client(void *params) { | |
char msg[BUF_SIZE]; | |
thread_param_t *p = (thread_param_t *) params; // thread params | |
// clear message buffer | |
memset(msg, 0, sizeof(msg)); | |
ticks = time(NULL); | |
snprintf(msg, sizeof(msg), "%.24s\r\n", ctime(&ticks)); | |
write(p->client_sock, msg, strlen(msg)); | |
printf("Sent message to Client #%d\n", p->client_sock); | |
// wait | |
usleep(10); | |
// clear message buffer | |
memset(msg, 0, sizeof(msg)); | |
// active close, It will remains in `TIME_WAIT` state. | |
if (close(p->client_sock) < 0) | |
error("Error: close()"); | |
free(p); | |
return NULL; | |
} | |
int main(int argc, char *argv[]) { | |
int listenfd = 0, connfd = 0; | |
struct sockaddr_in serv_addr; | |
// build server's internet addr and initialize | |
memset(&serv_addr, '0', sizeof(serv_addr)); | |
serv_addr.sin_family = AF_INET; // an internet addr | |
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // let the system figure out our IP addr | |
serv_addr.sin_port = htons(DEFAULT_PORT); // the port we will listen on | |
// create the socket, bind, listen | |
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
error("Error: socket()"); | |
if (bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) | |
error("Error: bind() Not enough privilleges(<1024) or already in use"); | |
if (listen(listenfd, BACKLOG) < 0) | |
error("Error: listen()"); | |
while (1) { | |
connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); | |
// memory allocation for `thread_param_t` struct | |
params = malloc(sizeof(thread_param_t)); | |
params->client_sock = connfd; | |
// 1 client, 1 thread | |
pthread_create(&thread_id, NULL, handle_client, (void *) params); | |
pthread_detach(thread_id); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment