1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > step5 . day6 网络编程 基于TCP协议的多并发模式(使用多进程 多线程 select函数分别实现)...

step5 . day6 网络编程 基于TCP协议的多并发模式(使用多进程 多线程 select函数分别实现)...

时间:2019-02-02 20:51:38

相关推荐

step5 . day6 网络编程 基于TCP协议的多并发模式(使用多进程 多线程 select函数分别实现)...

实现TCP服务器端多路并发的方法有①多进程②多线程③IO多路复用(select poll epoll函数)

1.多进程实现并发模式(仅在服务器端更改之前代码实现)

服务器端

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <linux/in.h>

#include <string.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <signal.h>

#include <sys/wait.h>

#define SIZE 128

void handler(int sign);

int main(int argc, const char *argv[])

{

if(argc<2){

printf("Usrmsg:%s <Port>\n",argv[0]);

return -1;

}

//1.创建套接字文件,用于链接

int socket_fd;

socket_fd = socket(AF_INET,SOCK_STREAM,0);

if(socket_fd == -1){

perror("socket");

return -1;

}

printf("socket Created ok\n");

//填充结构体sockaddr_in,用于传参

int bind_fd;

struct sockaddr_in serveraddr,connectaddr; //定义填充的结构体

bzero((void *)&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET; //IPV4协议

serveraddr.sin_port = htons(atoi(argv[1])); //本地端口号转化位网络字节码

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//本地IP转化位网络字节码,任意IP

//2.绑定socket文件描述符、端口、IP

bind_fd = bind(socket_fd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));

if(bind_fd == -1){

perror("bind");

return -1;

}

printf("bind ok\n");

//3.监听,将套接字文件属性该主动为被动模式

int listen_fd;

listen_fd = listen(socket_fd,10);

if(listen_fd == -1){

perror("listen");

return -1;

}

printf("listen ok\n");

int addrsize = sizeof(connectaddr);

int accept_fd;

int recvbyte;

char bufrecv[SIZE] = {0};

while(1){

accept_fd = accept(socket_fd,(struct sockaddr*)&connectaddr,&addrsize);

if(accept_fd == -1){

perror("accept");

return -1;

}

printf("connect ok\n");

pid_t pid = fork();

if(pid < 0){

perror("fork");

return -1;

}

if(pid == 0){

close(socket_fd);

while(1){

memset(bufrecv,0,SIZE);

int port = ntohs(connectaddr.sin_port);

char *ip = (char *)(inet_ntoa(connectaddr.sin_addr.s_addr));

recvbyte = recv(accept_fd, bufrecv,sizeof(bufrecv),0);

if(recvbyte <= 0){

printf("client failed connect\n");

return -1;

}

printf("IP:%s Port:%d online. send: %s\n",ip,port,bufrecv);

}

// close(accept_fd);

}

else{

close(accept_fd);

signal(SIGCHLD,handler);

}

}

close(socket_fd);

return 0;

}

void handler(int sign){

waitpid(-1,NULL,WNOHANG);

printf("signal = %d\n",sign);

}

2.多线程实现并发

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <linux/in.h>

#include <string.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <pthread.h>

#define SIZE 128

void *connectfun(void *arg);

int main(int argc, const char *argv[])

{

if(argc<2){

printf("Usrmsg:%s <Port>\n",argv[0]);

return -1;

}

//1.创建套接字文件,用于链接

int socket_fd;

socket_fd = socket(AF_INET,SOCK_STREAM,0);

if(socket_fd == -1){

perror("socket");

return -1;

}

printf("socket Created ok\n");

//填充结构体sockaddr_in,用于传参

int bind_fd;

struct sockaddr_in serveraddr,connectaddr; //定义填充的结构体

bzero((void *)&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET; //IPV4协议

serveraddr.sin_port = htons(atoi(argv[1])); //本地端口号转化位网络字节码

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//本地IP转化位网络字节码,任意IP

//2.绑定socket文件描述符、端口、IP

bind_fd = bind(socket_fd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));

if(bind_fd == -1){

perror("bind");

return -1;

}

printf("bind ok\n");

//3.监听,将套接字文件属性该主动为被动模式

int listen_fd;

listen_fd = listen(socket_fd,10);

if(listen_fd == -1){

perror("listen");

return -1;

}

printf("listen ok\n");

int addrsize = sizeof(connectaddr);

int accept_fd;

while(1){

accept_fd = accept(socket_fd,(struct sockaddr*)&connectaddr,&addrsize);

if(accept_fd == -1){

perror("accept");

return -1;

}

printf("connect ok\n");

pthread_t pid ;

pthread_create(&pid, NULL,connectfun,(void*)&accept_fd);

}

close(socket_fd);

return 0;

}

void *connectfun(void *arg){

pthread_detach(pthread_self());

char bufrecv[SIZE] = {0};

int recvbyte;

while(1){

memset(bufrecv,0,SIZE);

recvbyte = recv(*(int *)arg, bufrecv,sizeof(bufrecv),0);

if(recvbyte <= 0){

printf("client failed connect\n");

return NULL;

}

printf("send: %s\n",bufrecv);

}

}

3.select函数实现多并发

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <linux/in.h>

#include <string.h>

#include <sys/stat.h>

#include <fcntl.h>

#define SIZE 128

int main(int argc, const char *argv[])

{

if(argc<2){

printf("Usrmsg:%s <Port>\n",argv[0]);

return -1;

}

//1.创建套接字文件,用于链接

int socket_fd;

socket_fd = socket(AF_INET,SOCK_STREAM,0);

if(socket_fd == -1){

perror("socket");

return -1;

}

printf("socket Created ok\n");

//填充结构体sockaddr_in,用于传参

int bind_fd;

struct sockaddr_in serveraddr,connectaddr; //定义填充的结构体

bzero((void *)&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET; //IPV4协议

serveraddr.sin_port = htons(atoi(argv[1])); //本地端口号转化位网络字节码

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//本地IP转化位网络字节码,任意IP

//2.绑定socket文件描述符、端口、IP

bind_fd = bind(socket_fd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));

if(bind_fd == -1){

perror("bind");

return -1;

}

printf("bind ok\n");

//3.监听,将套接字文件属性该主动为被动模式

int listen_fd;

listen_fd = listen(socket_fd,10);

if(listen_fd == -1){

perror("listen");

return -1;

}

printf("listen ok\n");

//创建监听集合

fd_set readfds,tempfds;

//清空集合

FD_ZERO(&readfds);

FD_ZERO(&tempfds);

//将关心的文件描述符加入集合

FD_SET(0,&readfds);

FD_SET(socket_fd,&readfds);

//设置最大监听个数

int maxfd = socket_fd;

int addrsize = sizeof(connectaddr);

int accept_fd;

int recvbyte;

int val;

char bufsend[SIZE] = {0};

char bufrecv[SIZE] = {0};

while(1){

tempfds = readfds;

val = select(maxfd + 1,&tempfds,NULL,NULL,NULL);

//4.阻塞函数,等待客户链接请求,不关心链接的是那个客户端,填NULL

if(val < 0)

{

perror("select failed.");

return -1;

}

int i = 0;

for(i = 0;i<maxfd+1;i++){

if(FD_ISSET(i,&tempfds)){

if(i == 0)

{

fgets(bufsend,sizeof(bufsend),stdin);

send(socket_fd, bufsend, sizeof(bufsend),0);

printf("send ok.\n");

}

if(i == socket_fd)

{

accept_fd = accept(socket_fd,(struct sockaddr*)&connectaddr,&addrsize);

if(accept_fd == -1){

perror("accept");

return -1;

}

printf("accept ok\n");

int port = ntohs(connectaddr.sin_port);

char *ip = (char *)(inet_ntoa(connectaddr.sin_addr.s_addr));

printf("IP:%s Port:%d online.\n",ip,port);

FD_SET(accept_fd,&readfds);

maxfd = maxfd > accept_fd ? maxfd : accept_fd;

}

else{

recvbyte = recv(i, bufrecv,sizeof(bufrecv),0);

if(recvbyte <= 0)

{

FD_CLR(i,&readfds);

close(i);

continue;

}

printf("%s\n",bufrecv);

}

}

}

}

close(socket_fd);

close(accept_fd);

return 0;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。