欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 重头开始嵌入式第三十二天(TCP多客户端模型)

重头开始嵌入式第三十二天(TCP多客户端模型)

2025/4/3 6:14:29 来源:https://blog.csdn.net/qq_64792908/article/details/141861376  浏览:    关键词:重头开始嵌入式第三十二天(TCP多客户端模型)

1.多路IO

1.select

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
/* According to POSIX.1-2001, POSIX.1-2008 */
#include <sys/select.h>/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct sockaddr* (SA);
int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);//1 create set fd_set rd_set,tmp_set;FD_ZERO(&rd_set);FD_ZERO(&tmp_set);//2.add fd  FD_SET(listfd,&tmp_set);int maxfd = listfd;while(1){   rd_set = tmp_set;select(maxfd+1,&rd_set,NULL,NULL,NULL);int i = 0 ;//通讯套接字for(i = 0 ;i<maxfd+1;i++){if(FD_ISSET(i,&rd_set) && i ==listfd){int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");// exit(1);continue;}FD_SET(conn,&tmp_set);if(conn>maxfd)maxfd = conn;}if(FD_ISSET(i,&rd_set) && i!=listfd){int conn = i ;char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){FD_CLR(conn,&tmp_set);close(conn);printf("cli offline\n");break;}//printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}}close(listfd);return 0;
}

2.epoll

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>#include <sys/epoll.h>
typedef struct sockaddr* (SA);
int add_fd(int epfd,int fd)
{struct epoll_event ev;ev.events = EPOLLIN;ev.data.fd = fd;int ret = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);if(-1 == ret){perror("add fd");}return ret;
}
int del_fd(int epfd,int fd)
{struct epoll_event ev;ev.events = EPOLLIN;ev.data.fd = fd;int ret = epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);if(-1 == ret){perror("add fd");}return ret;
}int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);struct epoll_event rev[10]={0};//1 create set int epfd = epoll_create(10);if(-1 == epfd){perror("epoll_create");return 1;}// 2 .add fd  add_fd(epfd,listfd);while(1){    //3 wait event int ep_ret = epoll_wait(epfd,rev,10,-1);int i = 0 ;//4 find fd handlefor(i = 0 ;i<ep_ret;i++){if(rev[i].data.fd == listfd){    //通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");continue;}add_fd(epfd,conn);}else {int conn = rev[i].data.fd;char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){del_fd(epfd,conn);close(conn);break;}time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}}close(listfd);return 0;
}

2.并发模型

1.进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
typedef struct sockaddr* (SA);
void handle(int num)
{wait(NULL);
}
int main(int argc, char *argv[])
{signal(SIGCHLD,handle);//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);while(1){//通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");//exit(1);continue;}pid_t pid = fork();if(0 == pid){close(listfd);while(1){char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){printf("cli off line\n");close(conn);//break;exit(1);}printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}else if (pid>0){close(conn);}else{printf("fork");continue;}}close(listfd);return 0;
}

2.线程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
typedef struct sockaddr* (SA);void* th(void* arg)
{pthread_detach(pthread_self());int conn =* (int*)arg;//sem_post();while(1){char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){printf("cli off line\n");close(conn);break;}printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}return NULL;
}
int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);while(1){//通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");//exit(1);continue;}pthread_t tid;pthread_create(&tid,NULL,th,&conn);//sem_wait();// join();// 确保th中,把conn保存到局部变量中usleep(1000*5);}close(listfd);return 0;
}

3.循环

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#define PORT 8888#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};// 创建服务器套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到指定端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen failed");exit(EXIT_FAILURE);}while (1) {// 接受新的连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");exit(EXIT_FAILURE);}while (1) {int valread = read(new_socket, buffer, BUFFER_SIZE);if (valread <= 0) {break;}printf("Received from client: %s\n", buffer);send(new_socket, buffer, strlen(buffer), 0);memset(buffer, 0, BUFFER_SIZE);}close(new_socket);}return 0;}

 

 

 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词