linux select I/O共享服务端
来源:互联网 发布:php xss攻击过滤处理 编辑:程序博客网 时间:2024/06/08 13:38
花了两天时间,终于写好了一个select I/O复用服务端,真不容易,拿出来和大伙分享一下,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 will be connecting to#define BACKLOG 512 // how many pending connections queue will hold#define BUF_SIZE 1024#define MAX_PATH_LEN 255#ifndef bool #define bool int#endif#define FALSE 0#define TRUE 1typedef enum media_handle_e{ E_NONE = 0, E_PARSER = 1, E_TRANSCODE = 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, '\0', 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 fd 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;}
- linux select I/O共享服务端
- socket编程:多路复用I/O服务端客户端之select
- linux 的 I/O模型----select 相关
- Linux I/O复用:select ,poll,epoll
- 【Linux】I/O多路转接select
- Linux--高级I/O多路复用之select
- Linux复用I/O-Select-server代码
- I/O多路复用select
- I/O利用-select
- [文件I/O] select
- I/O Multiplexing & select
- I/O复用------select
- I/O复用-select
- 多路复用I/O--select
- I/O复用Select函数的UDP和TCP客户端和服务端
- Linux I/O多路复用之select,poll与epoll区别
- Linux的I/O多路转接模型和select()
- Linux I/O多路复用之select,poll与epoll区别
- opencv和matlab计时
- 关于青春
- mp3文件格式
- TCP/IP协议模型的相关知识
- NSPredicate的用法
- linux select I/O共享服务端
- Linux下rz,sz与ssh的配合使用
- Hdu 1171 Big Event in HDU
- 位图排序算法
- sql 修改 字段内的
- 单词冒泡排序算法
- 淡淡的微笑,静悄悄地过
- Flex使用cookie
- 在cxf web service类中同时注入spring bean出错时的解决办法