It took two days to finally write a select I/O multiplexing server, it's not easy, take it and share it with everyone, O (∩_∩) o~
/****************************************************************************** Copyright (C), 2001-2011, DCN Co.,
Ltd. File name:main.c Version: Initial Draft author:dong Shen created:2012/9/19 last Modified:Description:transcode main * /#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h > #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/queue.h > #include <m_type.h> #define MYPORT 1234//The port users are connecting to #define BACKLOG
A/How many pending connections queue'll hold #define BUF_SIZE 1024 #define MAX_PATH_LEN 255 #ifndef BOOL #define BOOL INT #endif #define FALSE 0 #define TRUE 1 typedef enum MEDIA_HANDLE_E {e_none = 0, E_parser = 1, E_tran
SCODE = 2}media_handle_e;
typedef enum PLATFORM_E {e_pf_none = 0, e_pf_pc = 1, E_pf_pad = 2, E_pf_phone = 3}platform_e;
typedef struct FD_A_T {int fd_a;
BOOL Need_write;
Media_handle_e Handle_type;
Char Path[max_path_len];
Char Out_path[max_path_len];
So_format_type Fmt_type;
SO_CODEC_ID V_codec;
SO_CODEC_ID A_codec;
int * bitrate;
int bitrate_count;
int width;
int height;
char * plat_form;
char * RET_BUF;
int Ret_buf_len;
Tailq_entry (fd_a_t) Fd_a_node;
}fd_a_t;
typedef tailq_head (Fd_a_list_t_, fd_a_t) fd_a_list_t;
int main (void) {int ret = 0; int sock_fd = 0; Listen on sock_fd int new_fd = 0; New connection on new_fd struct sockaddr_in server_addr; Server address information struct sockaddr_in client_addr;Connector ' s address information memset (&server_addr, 0, sizeof (struct sockaddr_in));
memset (&client_addr, 0, sizeof (struct sockaddr_in));
SOCK_FD = socket (af_inet, sock_stream, 0);
if ( -1 = sock_fd) {perror ("socket");
return-1;
int yes = 1;
ret = setsockopt (SOCK_FD, Sol_socket, so_reuseaddr, &yes, sizeof (int));
if ( -1 = ret) {perror ("setsockopt");
return-1; } server_addr.sin_family = Af_inet; Host byte order Server_addr.sin_port = Htons (MyPort); Short, network byte order server_addr.sin_addr.s_addr = Inaddr_any;
Automatically fill with my IP memset (Server_addr.sin_zero, ' I ', sizeof (Server_addr.sin_zero));
ret = bind (SOCK_FD, (struct sockaddr *) &server_addr, sizeof (SERVER_ADDR));
if ( -1 = ret) {perror ("bind");
return-1; RET = Listen (SOCK_FD, BACKLOG);
if ( -1 = ret) {perror ("listen");
return-1;
int maxsock = 0;
int conn_amount = 0;
fd_a_list_t FD_A_HD;
Tailq_init (&FD_A_HD);
Fd_set READ_FDSR;
Fd_set WRITE_FDSR;
Timeout setting//struct Timeval TV;
while (1) {//tv.tv_sec = 30;
tv.tv_usec = 0;
Initialize file descriptor set Fd_zero (&READ_FDSR);
Fd_zero (&WRITE_FDSR);
Fd_set (SOCK_FD, &READ_FDSR);
Fd_set (SOCK_FD, &WRITE_FDSR);
Maxsock = SOCK_FD;
fd_a_t * Cur_fd_node = Tailq_first (&FD_A_HD);
while (Cur_fd_node!= NULL) {fd_set (cur_fd_node->fd_a, &READ_FDSR);
Fd_set (cur_fd_node->fd_a, &WRITE_FDSR);
if (Cur_fd_node->fd_a > Maxsock) {maxsock = cur_fd_node->fd_a; } Cur_fd_node = TAILq_next (Cur_fd_node, Fd_a_node);
}//Select Read Write socket fd, READ_FDSR.
ret = SELECT (Maxsock + 1, &READ_FDSR, &WRITE_FDSR, NULL, NULL);
if (Ret < 0) {perror ("select");
Break
else if (ret = 0) {printf ("select timeout\n");
Continue
}//Check whether a new connection comes if (Fd_isset (SOCK_FD, &READ_FDSR)) {
int sin_size = sizeof (CLIENT_ADDR);
NEW_FD = Accept (sock_fd, (struct sockaddr *) &client_addr, &sin_size);
if (new_fd <= 0) {perror ("accept");
Continue }//Add to FD queue if (Conn_amount < BACKLOG) {//Create new F
d node, insert INTO FD list fd_a_t * New_fd_a_node = calloc (1, sizeof (fd_a_t));new_fd_a_node->fd_a = NEW_FD;
Tailq_insert_tail (&FD_A_HD, New_fd_a_node, Fd_a_node);
conn_amount++;
printf ("New connection client[%d]%s:%d\n", NEW_FD, Inet_ntoa (CLIENT_ADDR.SIN_ADDR), Ntohs (Client_addr.sin_port));
else {printf ("max connections arrive, exit\n");
Send (NEW_FD, "Bye", 4, 0);
Close (NEW_FD);
Continue
}//Check every FD in the set cur_fd_node = Tailq_first (&FD_A_HD);
while (Cur_fd_node!= NULL) {if (Fd_isset (cur_fd_node->fd_a, &READ_FDSR)) {
Char Recv_buf[buf_size] = {0};
int ret_len = recv (cur_fd_node->fd_a, Recv_buf, sizeof (RECV_BUF), 0); if (ret_len <= 0)//client Close {printf ("client[%d] close\n", CUR_FD_NODE->FD_A);
Close socket, clear fd_set close (cur_fd_node->fd_a);
Remove Fd_node from fd_list fd_a_t * next_fd_node = Tailq_next (Cur_fd_node, Fd_a_node);
Tailq_remove (&FD_A_HD, Cur_fd_node, Fd_a_node);
Free_node (Cur_fd_node);
Cur_fd_node = Next_fd_node;
conn_amount--;
Continue else//Receive data {printf ("Revice client[%d] msg:%s\n",
Cur_fd_node->fd_a, RECV_BUF);
Str_parser (Recv_buf, Ret_len, Cur_fd_node);
if (E_parser = = Cur_fd_node->handle_type) {media_parser (Cur_fd_node); else if (E_transcode = Cur_Fd_node->handle_type) {Media_transcode (Cur_fd_node);
else {;
} cur_fd_node->need_write = TRUE; } if (Fd_isset (cur_fd_node->fd_a, &WRITE_FDSR)) {if (TRUE = = Cur_fd_node->need_write) {printf ("Server send msg%s, Len%d\n", cur
_fd_node->ret_buf, Cur_fd_node->ret_buf_len);
Send (Cur_fd_node->fd_a, cur_fd_node->ret_buf, Cur_fd_node->ret_buf_len, 0);
Cur_fd_node->need_write = FALSE;
} Cur_fd_node = Tailq_next (Cur_fd_node, Fd_a_node);
} fd_a_t * Cur_fd_node = NULL;
while ((Cur_fd_node = Tailq_first (&FD_A_HD))!= NULL) {printf ("client[%d] close\n", cur_fd_node->fd_a);
Close socket, clear fd_set close (cur_fd_node->fd_a);
Remove Fd_node from Fd_list tailq_remove (&FD_A_HD, Cur_fd_node, Fd_a_node);
Free_node (Cur_fd_node);
conn_amount--;
return 1; }