今日任务

对于newfd的话,最好是另存然后传入给分支线程,避免父子线程操作同一个文件描述符
------------在tcp多线程服务端----------
如果使用全局变量,或者指针方式间接访问,会导致所有线程共用一份newfd和cin,那么newfd和cin会被覆盖
代码:
- #include
- #include
- #include
- #include
/* See NOTES */ - #include
- #include
- #include
- #include
-
-
-
- #define ERR_MSG(msg) do{\
- perror(msg);\
- fprintf(stderr,"__%d__",__LINE__);\
- }while(0)
- #define IP "192.168.125.255"
- #define PORT 8888
- /*
- * function: 广播,接收方
- * @param [ in]
- * @param [out]
- * @return
- */
-
- int main(int argc, const char *argv[])
- {
- //创建报式套接字
- int sfd=socket(AF_INET,SOCK_DGRAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket success");
- //绑定IIF(P和端口号(广播ip)
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(PORT);
- addr.sin_addr.s_addr=inet_addr(IP);
- socklen_t addrlen=sizeof(addr);
- if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
- ERR_MSG("bind");
- }
- puts("bind success");
- //存储发送方地址消息
- struct sockaddr_in source_addr;
- socklen_t source_addrlen=sizeof(source_addr);
- //循环接受消息
- char buf[128]="";
- while(1){
- bzero(buf,sizeof(buf));
- int recv_res=recvfrom(sfd,&buf,sizeof(buf),0,(struct sockaddr*)&source_addr,&source_addrlen);
- if(recv_res<0){
- ERR_MSG("recvfrom");
- return -1;
- }
- puts("recvfrom success");
- printf("[%s:%d]:%s\n",inet_ntoa(source_addr.sin_addr),ntohs(source_addr.sin_port),buf);
- }
- //关闭
- close(sfd);
- return 0;
- }
代码:
- #include
- #include
- #include
- #include
/* See NOTES */ - #include
- #include
- #include
- #include
-
-
-
- #define ERR_MSG(msg) do{\
- perror(msg);\
- fprintf(stderr,"__%d__",__LINE__);\
- }while(0)
- #define IP "192.168.125.255"
- #define PORT 8888
- /*
- * function: 广播,发送方
- * @param [ in]
- * @param [out]
- * @return
- */
-
- int main(int argc, const char *argv[])
- {
- //创建报式套接字
- int sfd=socket(AF_INET,SOCK_DGRAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket success");
- //设置允许广播
- int optval=1;//非0为允许
- socklen_t optlen=sizeof(optval);
- if(setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&optval,optlen)<0){
- ERR_MSG("setsockopt");
- return -1;
- }
-
- //IP和端口号(广播ip)
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(PORT);
- addr.sin_addr.s_addr=inet_addr(IP);
- socklen_t addrlen=sizeof(addr);
- //循环发送消息
- char buf[128]="";
- while(1){
- bzero(buf,sizeof(buf));
- printf("请输入>>>");
- fgets(buf,sizeof(buf),stdin);
- buf[strlen(buf)-1]='\0';
- if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,addrlen)<0){
- ERR_MSG("sendto");
- return -1;
- }
- puts("sendto success");
- }
- //关闭
- close(sfd);
- return 0;
- }
代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define ERR_MSG(msg) do{\
- perror(msg);\
- fprintf(stderr,"__%d__",__LINE__);\
- }while(0)
- #define IP "192.168.125.2"
- #define PORT 8888
- #define GRP_IP "224.1.2.3"
- /*
- * function: 组播:接收方
- * @param [ in]
- * @param [out]
- * @return
- */
- int main(int argc, const char *argv[])
- {
- //创建报式套接字
- int sfd=socket(AF_INET,SOCK_DGRAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket success");
-
- //加入多播组
- struct ip_mreqn mq;
-
- mq.imr_multiaddr.s_addr = inet_addr(GRP_IP); //组播IP
- mq.imr_address.s_addr = inet_addr(IP); //本机IP,ifconfig
- mq.imr_ifindex = 2; //网络设备索引号
-
- if(setsockopt(sfd,IPPROTO_IP, IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0){
- ERR_MSG("setsockopt");
- return -1;
- }
-
-
- //绑定IIF(P和端口号(广播ip)
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(PORT);
- addr.sin_addr.s_addr=inet_addr(GRP_IP);
- socklen_t addrlen=sizeof(addr);
- if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
- ERR_MSG("bind");
- }
- puts("bind success");
-
-
- //接受对方地址信息
- struct sockaddr_in source_addr;
- socklen_t source_addrlen=sizeof(source_addr);
-
- char buf[128]="";
-
- while(1){
-
- //接收消息
- bzero(buf,sizeof(buf));
- int recv_res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&source_addr, &source_addrlen);
- if(recv_res < 0)
- {
- ERR_MSG("recvfrom");
- return -1;
- }
-
- printf("[%s:%d] : %s\n", \
- inet_ntoa(source_addr.sin_addr), ntohs(source_addr.sin_port), buf);
- }
- //关闭
- close(sfd);
- return 0;
- }
代码
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define ERR_MSG(msg) do{\
- perror(msg);\
- fprintf(stderr,"__%d__",__LINE__);\
- }while(0)
- #define IP "192.168.125.2"
- #define PORT 8888
- #define GRP_IP "224.1.2.3"
- /*
- * function: 组播:发送方
- * @param [ in]
- * @param [out]
- * @return
- */
- int main(int argc, const char *argv[])
- {
- //创建报式套接字
- int sfd=socket(AF_INET,SOCK_DGRAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket success");
-
- //绑定IIF(P和端口号(广播ip)
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(PORT);
- addr.sin_addr.s_addr=inet_addr(GRP_IP);
- socklen_t addrlen=sizeof(addr);
- if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
- ERR_MSG("bind");
- }
- puts("bind success");
-
-
-
- char buf[128]="";
-
- while(1){
-
- //发送消息
- bzero(buf,sizeof(buf));
- printf("请输入>>> ");
- fgets(buf, sizeof(buf), stdin);
- buf[strlen(buf)-1] = 0;
-
- //发送数据, 主动发送给指定接收放,例如这里可以主动发给接收方
- if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)
- {
- ERR_MSG("sendto");
- return -1;
- }
- printf("sendto success\n");
- }
- //关闭
- close(sfd);
- return 0;
- }
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- //自定义报错提示
- #define ERR_MSG(msg) do{\
- fprintf(stderr,"__%d__",__LINE__);\
- perror(msg);\
- }while(0)
- #define SER_PORT 8888
- #define SER_IP "192.168.125.2"
- /*
- * function: TCP服务端
- * @param [ in]
- * @param [out]
- * @return
- */
-
- int recv_send(int cfd,struct sockaddr_in cli_addr);
- void handle(int sig){
- while(waitpid(-1,NULL,WNOHANG)>0);
- return ;
- }
-
- int main(int argc, const char *argv[])
- {
- //监听回收僵尸进程
- if(signal(SIGCHLD,handle)==SIG_ERR){
- ERR_MSG("signal");
- return -1;
- }
-
- //1.创建socket套接字,
- int sfd=socket(AF_INET,SOCK_STREAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket create");
-
- //允许端口快速复用
- int reuse = 1;
- if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
- {
- ERR_MSG("setsockopt");
- return -1;
- }
- printf("允许端口快速复用成功\n");
- //2.绑定服务器IP和端口号bind
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(SER_PORT);
- addr.sin_addr.s_addr=inet_addr(SER_IP);
- if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr))<0){
- ERR_MSG("bind");
- return -1;
- }
- puts("bind success");
-
-
- //3.建立监听listen
- if(listen(sfd,128)<0){
- ERR_MSG("listen");
- return -1;
- }
- puts("listen suucess");
-
-
- //4.等待客户端连接, accept
- struct sockaddr_in cli_addr;
- socklen_t cli_addrlen=sizeof(cli_addr);
- pid_t pid;
- while(1){
- int cfd=accept(sfd,(struct sockaddr*)&cli_addr,&cli_addrlen);
- if(cfd<0){
- ERR_MSG("accept");
- return -1;
- }
- puts("accept");
- pid=fork();
- if(pid==0){
- //子进程执行信息收发
- recv_send(cfd,cli_addr);
- exit(0);
- }else if(pid<0){
- ERR_MSG("fork");
- return -1;
- }
- close(cfd);
-
- }
- //6.关闭
- close(sfd);
-
-
- return 0;
- }
- int recv_send(int cfd,struct sockaddr_in cli_addr){
- //5.接受发送消息recv;send
- char buf[128];
- while(1){
- bzero(buf,sizeof(buf));
- int recv_res=recv(cfd,buf,sizeof(buf),0);
-
- if(recv_res<0){
- ERR_MSG("recv");
- return -1;
- }else if(recv_res==0){
- printf("socket peer has shutdown\n");
- break;
- }
- puts("recv success");
- printf("[%s:%d]:%s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port),buf);
- if(strcmp(buf,"quit")==0)
- break;
-
- strcat(buf,"-----i has received");
- int send_res=send(cfd,buf,sizeof(buf),0);
- if(send_res<0){
- ERR_MSG("send");
- return -1;
- }
- puts("send success");
- }
- }
代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- //自定义报错提示
- #define ERR_MSG(msg) do{\
- fprintf(stderr,"__%d__",__LINE__);\
- perror(msg);\
- }while(0)
- #define SER_PORT 8888
- #define SER_IP "192.168.125.2"
- struct cliMsg{
- int cfd;
- struct sockaddr_in cli_addr;
- };
- /*
- * function: TCP服务端
- * @param [ in]
- * @param [out]
- * @return
- */
- void* recv_send(void*arg);
- int main(int argc, const char *argv[])
- {
- //1.创建socket套接字,
- int sfd=socket(AF_INET,SOCK_STREAM,0);
- if(sfd<0){
- ERR_MSG("socket");
- return -1;
- }
- puts("socket create");
-
- //允许端口快速复用
- int reuse = 1;
- if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
- {
- ERR_MSG("setsockopt");
- return -1;
- }
- printf("允许端口快速复用成功\n");
- //2.绑定服务器IP和端口号bind
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(SER_PORT);
- addr.sin_addr.s_addr=inet_addr(SER_IP);
- if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr))<0){
- ERR_MSG("bind");
- return -1;
- }
- puts("bind success");
-
-
- //3.建立监听listen
- if(listen(sfd,128)<0){
- ERR_MSG("listen");
- return -1;
- }
- puts("listen suucess");
-
-
- //4.等待客户端连接, accept
- struct sockaddr_in cli_addr;
- socklen_t cli_addrlen=sizeof(cli_addr);
- pthread_t pth;
- while(1){
-
- int cfd=accept(sfd,(struct sockaddr*)&cli_addr,&cli_addrlen);
- if(cfd<0){
- ERR_MSG("accept");
- return -1;
- }
- puts("accept");
- struct cliMsg climsg;
- climsg.cfd=cfd;
- climsg.cli_addr=cli_addr;
- //创建调用线程执行
- if(pthread_create(&pth,NULL,recv_send,(void *)&climsg)!=0){
- fprintf(stderr,"pthread_create failed __%d__\n",__LINE__);
- return -1;
- }
- pthread_detach(pth);
-
- }
- close(sfd);
-
- return 0;
- }
- void* recv_send(void*arg){
- //5.接受发送消息recv;send
- int cfd=((struct cliMsg*)arg)->cfd;
- struct sockaddr_in cli_addr=((struct cliMsg*)arg)->cli_addr;
-
- char buf[128];
- while(1){
- bzero(buf,sizeof(buf));
- int recv_res=recv(cfd,buf,sizeof(buf),0);
-
- if(recv_res<0){
- ERR_MSG("recv");
- break;
- }else if(recv_res==0){
- printf("socket peer has shutdown\n");
- break;
- }
- puts("recv success");
- printf("[%s:%d]:%s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port),buf);
- if(strcmp(buf,"quit")==0)
- break;
-
- strcat(buf,"-----i has received");
- int send_res=send(cfd,buf,sizeof(buf),0);
- if(send_res<0){
- ERR_MSG("send");
- break;
- }
- puts("send success");
- }
- close(cfd);
- pthread_exit(NULL);
- }
今日思维导图

不知道最近确实是脑子比较慢,还是拖拉,做事太慢了,tcp的代码还没复敲;