Linux网络编程【三】:TCP服务器多进程和多线程(http访问)版本
2017-06-02 00:41
1861 查看
为了让服务器同时接受多个客户端访问,所以需要多进程或者多线程
多进程版本:
多线程(HTTP)版本:
效果如图:
多进程版本:
#include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<string.h> static void usage(const char* proc) { printf("%s [ip] [port]", proc); } int startup(const char* _ip, int _port) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("socket"); return 2; } struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); //允许创建多个端口号相同但IP不同的套接字 int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) { perror("bind"); return 3; } if(listen(sock, 5) < 0) { perror("listen"); return 4; } return sock; } int main(int argc, char* argv[]) { if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); char buf[10240]; struct sockaddr_in client; socklen_t len = sizeof(client); while(1) { int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len); if(new_sock < 0) { perror("accept"); continue; } //多进程模式 pid_t id = fork(); if(id > 0) { //father close(new_sock); if(fork() > 0) { return 0; } } else if(id == 0) { //child close(listen_sock); printf("connect... ip is: %s port is: %d \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while(1) { ssize_t s = read(new_sock, buf, sizeof(buf)-1); if(s > 0) { buf[s] = '\0'; printf("client say# %s\n",buf); write(new_sock, buf, strlen(buf)); } else if(s == 0) { printf("client quit ...\n"); break; } else break; } return 0; } else { perror("fork"); close(listen_sock); return 0; } } return 0; }
多线程(HTTP)版本:
#include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<string.h> static void usage(const char* proc) { printf("%s [ip] [port]", proc); } int startup(const char* _ip, int _port) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("socket"); return 2; } struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); //允许创建多个端口号相同但IP不同的套接字 int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) { perror("bind"); return 3; } if(listen(sock, 5) < 0) { perror("listen"); return 4; } return sock; } void* handler(void* arg) { char buf[10240]; int newsock = (int)arg; //printf("connect... ip is: %s port is: %d \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while(1) { ssize_t s = read(newsock, buf, sizeof(buf)-1); if(s > 0) { const char* msg = "HTTP/1.1 200 OK\r\n\r\n<html><h1>hello world</h1></html>\r\n"; buf[s] = '\0'; printf("- message:%s\n ",buf); write(newsock, msg, strlen(msg)); } else if(s == 0) { printf("client quit ...\n"); break; } else break; } } int main(int argc, char* argv[]) { if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); //char buf[10240]; struct sockaddr_in client; socklen_t len = sizeof(client); while(1) { int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len); if(new_sock < 0) { perror("accept"); return 2; } printf("connect success...\n ip is: %s port is: %d \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); //多线程模式 pthread_t tid; if(pthread_create(&tid, NULL, handler, (void*)new_sock)<0) { perror("pthread"); return 3; } pthread_detach(&tid); } return 0; }
效果如图:
相关文章推荐
- 【Linux网络编程】基于TCP单进程版本阻塞式客户端/服务器
- 【Linux网络编程】基于TCP多进程(fork)版本客户端/服务器
- Linux网络编程:TCP服务器(单进程多用户),使用select方法实现
- linux网络编程之多线程多进程服务器与进程线程池
- Linux网络编程【六】:TCP协议高性能服务器(http)模型之I/O多路转接epoll
- Linux网络编程 基于tcp的多线程的服务器
- Linux网络编程 之 TCP 多线程的服务器和客户端同时收发数据
- 【Linux网络编程】基于TCP的多线程(pthread)版本最简陋的HTTP服务器
- Linux 网络编程详解六(多进程服务器僵尸进程解决方案)
- Android网络编程之URLConnection和HttpClient访问服务器
- linux网络编程----->高并发--->多线程并发服务器
- 网络编程资料总结(二)----Tcp多线程服务器和客户端的实现
- 网络编程(6)单进程多线程并发服务器实现
- Linux系统网络编程中TCP通讯socket--send导致进程被关闭
- Linux网络编程--tcp服务器
- Linux网络编程一步一步学-编写一个HTTP协议的目录浏览和文件下载服务器
- Linux网络编程——tcp并发服务器(I/O复用之select)
- iOS 各种网络编程总结--进程、线程、Socket、HTTP、TCP/IP、TCP和UDP
- linux网络编程--服务器客户端(TCP实现)
- Linux网络编程一步一步学-自己编写一个HTTP协议的目录浏览和文件下载服务器