tcp多线程并发服务器
2016-09-02 11:11
232 查看
tcp多线程并发服务器
多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建。据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为“轻量级”进程。线程与进程不同的是:一个进程内的所有线程共享相同的全局内存、全局变量等信息,这种机制又带来了同步问题。
tcp多线程并发服务器框架:
我们在使用多线程并发服务器时,可以直接使用以上框架,我们仅仅修改线程函数里面的内容。
代码示例:
特别注意:
如果void *是4个字节,而connfd为int类型也是4个字节,可以传值。但是connfd为char、short,上面传值就会出错。所以一般不要(不推荐)在线程中传递connfd ,会造成数据丢失,同时会造成多个服务器连接错误。对服务器造成不可预知的问题.
多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建。据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为“轻量级”进程。线程与进程不同的是:一个进程内的所有线程共享相同的全局内存、全局变量等信息,这种机制又带来了同步问题。
tcp多线程并发服务器框架:
我们在使用多线程并发服务器时,可以直接使用以上框架,我们仅仅修改线程函数里面的内容。
代码示例:
/************************************************************************* > File Name: tcpServer.c > Author: ************************************************************************/ #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/select.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> int listenfd = -1; // 套接字 int connfd = -1; #define PORT 8080 // 监听端口 #define UNUSED(x) (void)x /************************************************************************ 函数名称: void *read_thread(void *arg) 函数功能: 线程函数,处理客户信息 函数参数: 无 函数返回: 无 ************************************************************************/ void *read_thread(void *arg) { char rxbuf[1024] = {0,}; UNUSED(arg); while(1) { //recv with timeout fd_set fdset; struct timeval timeout; int retv = 0, readn = 0; FD_ZERO(&fdset); FD_SET(connfd, &fdset); timeout.tv_sec = 2; timeout.tv_usec = 0; retv = select(connfd+1, &fdset, NULL, NULL, &timeout); if (retv == -1) { printf("%s: Select: failed. retv=%d", __func__, retv); close(connfd); break; }else if (retv == 0) { usleep(500); // 1毫秒 continue; } memset(rxbuf,0,sizeof(rxbuf)); readn = recv(connfd, rxbuf, sizeof(rxbuf), 0); if (readn < 0) { if (errno == EINTR) { printf("%s: recv failed", __func__); usleep(500); continue; } else { printf("%s: recv timeout. readn=%d, error=%s", __func__, readn, strerror(errno)); close(connfd); usleep(500); break; } }else if (readn == 0) { usleep(500); continue; } } close(connfd); return NULL; } //=============================================================== // 语法格式: void main(void) // 实现功能: 主函数,建立一个TCP并发服务器 // 入口参数: 无 // 出口参数: 无 //=============================================================== int main(int argc, char *argv[]) { int no; struct sockaddr_in my_addr; // 服务器地址结构体 listenfd = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字 if(listenfd < 0) { perror("socket error"); exit(-1); } /* Enable address reuse */ on = 1; setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); bzero(&my_addr, sizeof(my_addr)); // 初始化服务器地址 my_addr.sin_family = AF_INET; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); printf("Binding server to port %d\n", port); // 绑定 if(bind(listenfd, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { perror("bind"); close(listenfd); exit(-1); } // 监听,套接字变被动 if( listen(listenfd, 10) < 0) { perror("listen"); close(listenfd); exit(-1); } printf("Waiting client...\n"); while(1) { struct sockaddr_in client_addr; // 用于保存客户端地址 socklen_t cliaddr_len = sizeof(client_addr); // 必须初始化!!! //获得一个已经建立的连接 connfd = accept(listenfd, (struct sockaddr*)&client_addr, &cliaddr_len); if(connfd < 0) { perror("accept this time"); continue; } // 打印客户端的 ip printf("client from : %s\n", inet_ntoa(client_addr.sin_addr))) printf("----------------------------------------------\n"); if(connfd > 0) { pthread_t thread_id; //由于同一个进程内的所有线程共享内存和变量,因此在传递参数时需作特殊处理,值传递。 pthread_create(&thread_id, NULL, read_thread, NULL); //创建线程 pthread_detach(thread_id); // 线程分离,结束时自动回收资源 } } close(listenfd); return 0; }
特别注意:
如果void *是4个字节,而connfd为int类型也是4个字节,可以传值。但是connfd为char、short,上面传值就会出错。所以一般不要(不推荐)在线程中传递connfd ,会造成数据丢失,同时会造成多个服务器连接错误。对服务器造成不可预知的问题.
相关文章推荐
- 高性能、高并发TCP服务器(多线程调用libevent)
- 高性能、高并发TCP服务器(多线程调用libevent)
- Linux网络编程——tcp并发服务器(多线程)
- 实现TCP并发服务器之二(多线程)
- 高性能、高并发TCP服务器(多线程调用libevent)
- 高性能、高并发TCP服务器(多线程调用libevent)
- lesson6 基于多线程的tcp并发服务器
- 黑马程序员-TCP上传图片-多线程并发上传图片-客户端并发登陆-自定义服务器
- 高性能、高并发TCP服务器(多线程调用libevent)
- 高性能、高并发TCP服务器(多线程调用libevent)
- TCP多线程并发服务器+线程池+echo
- 高性能、高并发TCP服务器(多线程调用libevent)
- 流式(TCP)套接字客户端/服务器编程 (多线程并发服务器)
- 高性能、高并发TCP服务器(多线程调用libevent)
- Linux网络编程——tcp并发服务器(多线程)
- 高性能、高并发TCP服务器(多线程调用libevent)
- 高性能、高并发TCP服务器(多线程调用libevent)
- Linux网络编程——tcp并发服务器(多线程)
- 高性能、高并发TCP服务器(多线程调用libevent)
- 高性能、高并发TCP服务器(多线程调用libevent)