Skip to content

Instantly share code, notes, and snippets.

@likejazz
Last active August 29, 2015 14:22
Show Gist options
  • Save likejazz/aaacad19644c2b5cb13e to your computer and use it in GitHub Desktop.
Save likejazz/aaacad19644c2b5cb13e to your computer and use it in GitHub Desktop.
How to handle TIME_WAIT state
#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