UDP广播、组播;TCP多进程

UDP广播

接收方 

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <unistd.h>
  5 #include <arpa/inet.h>
  6 #include <netinet/in.h>
  7 #include <string.h>
  8 
  9 #define IP "192.168.124.255"     //ifconfig查看
 10 #define PORT 6666             //端口号的网络字节序(在1014-49
 11 #define ERR_MSG(msg) do{\
 12     fprintf(stderr,"line=%d \n",__LINE__);\
 13     perror(msg);\
 14 }while(0)
 15 int main(int argc, const char *argv[])
 16 {
 17     //创建报式套接字
 18     int sfd = socket(AF_INET,SOCK_DGRAM,0);
 19     if (sfd < 0)
 20     {
 21         ERR_MSG("socket");
 22         return -1;
 23     }
 24     printf("流式套接字创建成功\n");
 25     //允许端口被快速使用
 26     int reuse = 1;
 27     if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
 28     {
 29         ERR_MSG("setsockopt");
 30         return -1;
 31     }
 32     printf("允许端口快速重用\n");                                                                 
 33     //填充服务器的地址信息结构体,给bind函数使用
 34     //真实的地址信息结构体根据地址族制定,AF_INET-->main 7 ip
 35     struct sockaddr_in sin;
 36     sin.sin_family      = AF_INET;//必须填AF_INET(代表是流式套接字)
 37     sin.sin_port        = htons(PORT);//端口号的网络字节序
 38                                         //(htons代表是将主机字节序转换为网络字节序)
 39     sin.sin_addr.s_addr = inet_addr(IP);//本机IP,ifconfig查看,
 40                                         //inet_addr是.十进制转换为网络字节序
 41 
 42     //绑定服务器的地址信息,必须绑定
 43     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 44     {
 45         ERR_MSG("bind");
 46         return -1;
 47     }
 48     printf("绑定成功\n");
 49     char buf[128]="";
 50     //获取连接成功的客户端信息,生成一个新的套接字文件描述符
 51     struct sockaddr_in cin;
 52     socklen_t addrlen = sizeof(cin);
 53 
 54     while(1)
 55     {
 56         //接收数据
 57         bzero(buf,sizeof(buf));
 58         if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen)<0);
 59         {
 60             ERR_MSG("recvform");
 61             return -1;
 62         }
 63         /*
 64         //发送
 65         strcat(buf,"*__*");
 66         if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin))<0)
 67         {
 68             ERR_MSG("sendto");
 69             return -1;
 70         }
 71         printf("发送成功\n");
 72         */
 73     }
 74 
 75     //关闭文件描述符
 76     if(close(sfd)< 0)
 77     {
 78         ERR_MSG("close");
 79         return -1;
 80     }
 81     printf("sfd关闭成功 \n");
 82 
 83 
 84 
 85     return 0;
 86 }
 87 

发送方 

 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <unistd.h>
 5 #include <arpa/inet.h>
 6 #include <netinet/in.h>
 7 #include <string.h>
 8 
 9 #define IP "192.168.124.255"     //ifconfig查看
10 #define PORT 6666              //端口号的网络字节序(在1014-49
11 #define ERR_MSG(msg) do{\
12     fprintf(stderr,"line=%d \n",__LINE__);\
13     perror(msg);\
14 }while(0)
15 int main(int argc, const char *argv[])
16 {
17     //创建报式套接字
18     int sfd = socket(AF_INET,SOCK_DGRAM,0);
19     if (sfd < 0)
20     {
21         ERR_MSG("socket");
22         return -1;
23     }
24     printf("流式套接字创建成功\n");
25 
26     //允许端口被快速使用
27     int reuse = 1;
28     if(setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&reuse,sizeof(reuse))<0)
29     {
30         ERR_MSG("setsockopt");
31         return -1;
32     }
33     printf("允许端口快速重用\n");
34 
35     //填充服务器的地址信息结构体,给sendto函数使用
36     //代表将数据发送给指定的对端
37     struct sockaddr_in sin;
38     sin.sin_family      = AF_INET;//必须填AF_INET(代表是流式套接字)
39     sin.sin_port        = htons(PORT);//端口号的网络字节序,对端绑定的端口
40                                         //(htons代表是将主机字节序转换为网络字节序)
41     sin.sin_addr.s_addr = inet_addr(IP);//对端的IP,ifconfig查看,
42                                         //inet_addr是.十进制转换为网络字节序
43 
44     char buf[128]="";
45     //获取连接成功的客户端信息,生成一个新的套接字文件描述符
46     struct sockaddr_in cin;
47     socklen_t addrlen = sizeof(cin);
48 
49     while(1)
50     {
51         bzero(buf,sizeof(cin));
52         //发送
53         printf("请输入>>>");
54         fgets(buf,sizeof(buf),stdin);
55         buf[strlen(buf)-1] = '\0';                                                                                                    
56         if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0)
57         {
58             ERR_MSG("sendto");
59             return -1;
60         }
61         printf("发送成功\n");
62         /*
63         //接收数据
64 
65         bzero(buf,sizeof(buf));
66         if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen)<0);
67         {
68             ERR_MSG("recvform");
69             return -1;
70         }
71         printf("[%s  %d]  %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
72         */
73     }
74 
75     //关闭文件描述符
76     if(close(sfd)< 0)
77     {
78         ERR_MSG("close");
79         return -1;
80     }
81     printf("sfd关闭成功 \n");
82 
83 
84 
85     return 0;
86 }
87 

运行结果

 

UDP组播

接收方

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <unistd.h>
  5 #include <arpa/inet.h>
  6 #include <netinet/in.h>
  7 #include <string.h>
  8 
  9 #define GRP_IP "224.1.2.3"     //ifconfig查看
 10 #define PORT 6666             //端口号的网络字节序(在1014-49151之间)
 11 #define LOC_IP "192.168.124.47"
 12 #define ERR_MSG(msg) do{\
 13     fprintf(stderr,"line=%d \n",__LINE__);\
 14     perror(msg);\
 15 }while(0)
 16 int main(int argc, const char *argv[])
 17 {
 18     //创建报式套接字
 19     int sfd = socket(AF_INET,SOCK_DGRAM,0);
 20     if (sfd < 0)
 21     {
 22         ERR_MSG("socket");
 23         return -1;
 24     }
 25     printf("流式套接字创建成功\n");
 26     //允许端口被快速使用
 27     int reuse = 1;
 28     if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
 29     {
 30         ERR_MSG("setsockopt");
 31         return -1;
 32     }
 33     printf("允许端口快速重用\n");
 34 
 35     //加入多播组
 36     struct ip_mreqn mq;
 37     mq.imr_multiaddr.s_addr = inet_addr(GRP_IP); //要加入的小组IP
 38     mq.imr_address.s_addr = inet_addr(LOC_IP);   //本机IP
 39     mq.imr_ifindex = 0;                          //网络设备索引号
 40     if(setsockopt(sfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0)
 41     {
 42         ERR_MSG("setsockopt");
 43         return -1;                                                                                       
 44     }
 45     printf("加入小组[%s %d]成功\n",GRP_IP,PORT);
 46 
 47     //填充服务器的地址信息结构体,给bind函数使用
 48     //真实的地址信息结构体根据地址族制定,AF_INET-->main 7 ip
 49     struct sockaddr_in sin;
 50     sin.sin_family      = AF_INET;//必须填AF_INET(代表是流式套接字)
 51     sin.sin_port        = htons(PORT);//端口号的网络字节序
 52                                         //(htons代表是将主机字节序转换为网络字节序)
 53     sin.sin_addr.s_addr = inet_addr(GRP_IP);//本机IP,ifconfig查看,
 54                                         //inet_addr是.十进制转换为网络字节序
 55 
 56     //绑定服务器的地址信息,必须绑定
 57     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 58     {
 59         ERR_MSG("bind");
 60         return -1;
 61     }
 62     printf("绑定成功\n");
 63     char buf[128]="";
 64     //获取连接成功的客户端信息,生成一个新的套接字文件描述符
 65     struct sockaddr_in cin;
 66     socklen_t addrlen = sizeof(cin);
 67 
 68     while(1)
 69     {
 70         //接收数据
 71         bzero(buf,sizeof(buf));
 72         if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen)<0);
 73         {
 74             ERR_MSG("recvform");
 75             return -1;
 76         }
 77         /*
 78         //发送
 79         strcat(buf,"*__*");
 80         if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin))<0)
 81         {
 82             ERR_MSG("sendto");
 83             return -1;
 84         }
 85         printf("发送成功\n");
 86         */
 87     }
 88 
 89     //关闭文件描述符
 90     if(close(sfd)< 0)
 91     {
 92         ERR_MSG("close");
 93         return -1;
 94     }
 95     printf("sfd关闭成功 \n");
 96 
 97 
 98 
 99     return 0;
100 }
101 

发送方

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <unistd.h>
  5 #include <arpa/inet.h>
  6 #include <netinet/in.h>
  7 #include <string.h>
  8 
  9 #define GRP_IP "224.1.2.3"     //ifconfig查看
 10 #define PORT 6666              //端口号的网络字节序(在1014-49151之间)
 11 #define LOC_IP "224.168.124.47"
 12 #define ERR_MSG(msg) do{\
 13     fprintf(stderr,"line=%d \n",__LINE__);\
 14     perror(msg);\
 15 }while(0)
 16 int main(int argc, const char *argv[])
 17 {
 18     //创建报式套接字
 19     int sfd = socket(AF_INET,SOCK_DGRAM,0);
 20     if (sfd < 0)
 21     {
 22         ERR_MSG("socket");
 23         return -1;
 24     }
 25     printf("流式套接字创建成功\n");
 26     /*
 27     //允许端口被快速使用
 28     int reuse = 1;
 29     if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
 30     {
 31         ERR_MSG("setsockopt");
 32         return -1;
 33     }
 34     printf("允许端口快速重用\n"); 
 35     */
 36     //填充服务器的地址信息结构体,给sendto函数使用
 37     //代表将数据发送给指定的对端
 38     struct sockaddr_in sin;
 39     sin.sin_family      = AF_INET;//必须填AF_INET(代表是流式套接字)
 40     sin.sin_port        = htons(PORT);//端口号的网络字节序,对端绑定的端口
 41                                         //(htons代表是将主机字节序转换为网络字节序)
 42     sin.sin_addr.s_addr = inet_addr(GRP_IP);//对端的IP,ifconfig查看,
 43                                         //inet_addr是.十进制转换为网络字节序
 44     /*
 45     //绑定服务器的地址信息,必须绑定
 46     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 47     {
 48         ERR_MSG("bind");
 49         return -1;
 50     }
 51     printf("绑定成功\n");
 52     */
 53     char buf[128]="";
 54     //获取连接成功的客户端信息,生成一个新的套接字文件描述符
 55     struct sockaddr_in cin;
 56     socklen_t addrlen = sizeof(cin);
 57 
 58     while(1)
 59     {
 60         bzero(buf,sizeof(cin));
 61         //发送                                                                                      
 62         printf("请输入>>>");
 63         fgets(buf,sizeof(buf),stdin);
 64         buf[strlen(buf)-1] = '\0';
 65         if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0)
 66         {
 67             ERR_MSG("sendto");
 68             return -1;
 69         }
 70         printf("发送成功\n");
 71         /*
 72         //接收数据
 73 
 74         bzero(buf,sizeof(buf));
 75         if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen)<0);
 76         {
 77             ERR_MSG("recvform");
 78             return -1;
 79         }
 80         printf("[%s  %d]  %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
 81     */
 82     }
 83 
 84     //关闭文件描述符
 85     if(close(sfd)< 0)
 86     {
 87         ERR_MSG("close");
 88         return -1;
 89     }
 90     printf("sfd关闭成功 \n");
 91 
 92 
 93 
 94     return 0;
 95 }
 96 
~                                                                                                       
~                                                                                                       

运行结果

 

TCP多进程

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <unistd.h>
  5 #include <arpa/inet.h>
  6 #include <netinet/in.h>
  7 #include <string.h>
  8 #include <stdlib.h>
  9 #include <sys/wait.h>
 10 #include <signal.h>
 11 
 12 #define IP "192.168.124.47"     //ifconfig查看
 13 #define PORT 8888              //端口号的网络字节序(在1014-49151之间)
 14 #define ERR_MSG(msg) do{\
 15     fprintf(stderr,"line=%d \n",__LINE__);\
 16     perror(msg);\
 17 }while(0)
 18 
 19 int deal_cli_msg(int newsfd,struct sockaddr_in cin);
 20 
 21 void handler(int sig)//回收僵尸进程
 22 {
 23     while(waitpid(-1,NULL,WNOHANG)>0);
 24 }
 25 int main(int argc, const char *argv[])
 26 {
 27     //捕获17号信号
 28     if(signal(SIGCHLD,handler) == SIG_ERR)
 29     {
 30         ERR_MSG("signal");
 31         return -1;
 32     }
 33 
 34     //创建流式套接字
 35     int sfd = socket(AF_INET,SOCK_STREAM,0);
 36     if (sfd < 0)
 37     {
 38         ERR_MSG("socket");
 39         return -1;
 40     }
 41     printf("流式套接字创建成功\n");                                                                                                                                                   
 42     //允许端口被快速使用
 43     int reuse = 1;
 44     if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
 45     {
 46         ERR_MSG("setsockopt");
 47         return -1;
 48     }
 49     printf("允许端口快速重用\n");
 50     //填充服务器的地址信息结构体,给bind函数使用
 51     //真实的地址信息结构体根据地址族制定,AF_INET-->main 7 ip
 52     struct sockaddr_in sin;
 53     sin.sin_family      = AF_INET;//必须填AF_INET(代表是流式套接字)
 54     sin.sin_port        = htons(PORT);//端口号的网络字节序
 55     //(htons代表是将主机字节序转换为网络字节序)
 56     sin.sin_addr.s_addr = inet_addr(IP);//本机IP,ifconfig查看,
 57     //inet_addr是.十进制转换为网络字节序
 58 
 59     //绑定服务器的地址信息,必须绑定
 60     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 61     {
 62         ERR_MSG("bind");
 63         return -1;
 64     }
 65     printf("绑定成功\n");
 66     //将套接字设置为被监听状态
 67     if (listen(sfd,128)< 0)
 68     {
 69         ERR_MSG("listen");
 70         return -1;
 71     }
 72     printf("监听成功\n");
 73     //获取连接成功的客户端信息,生成一个新的套接字文件描述符
 74     struct sockaddr_in cin;
 75     socklen_t addrlen = sizeof(cin);
 76 
 77     int newsfd;
 78     pid_t pid;
 79     while(1)
 80     {
 81         newsfd = accept(sfd,(struct sockaddr * )&cin,&addrlen);
 82         if(newsfd < 0)
 83         {
 84             ERR_MSG("accept");
 85             return -1;
 86         }
 87         printf("[%s %d] newsfd=%d 客户端连接成功\n",inet_ntoa(cin.sin_addr),\
 88                 ntohs(cin.sin_port),newsfd);
 89         pid = fork();
 90         if(pid == 0)
 91         {
 92             close(sfd);
 93             deal_cli_msg(newsfd,cin);
 94             exit(0);
 95         }
 96         close(newsfd);
 97     }
 98 
 99     //关闭文件描述符
100     if(close(newsfd)<0)
101     {
102         ERR_MSG("close");
103         return -1;
104     }
105     printf("newsfd关闭成功\n");
106 
107     return 0;
108 }
109 int deal_cli_msg(int newsfd,struct sockaddr_in cin)
110 {
111     char buf[128]="";
112     ssize_t res;
113     while(1)
114     {
115         bzero(buf,sizeof(buf));
116         res = recv(newsfd,buf,sizeof(buf),0);
117         if(res < 0)
118         {
119             ERR_MSG("recv");
120             return -1;
121         }
122         else if(res == 0)
123         {
124             printf("[%s %d] newsfd=%d 客户端下线\n",inet_ntoa(cin.sin_addr),\
125                     ntohs(cin.sin_port),newsfd);
126             break;
127         }
128         printf("[%s %d] newsfd = %d ; %s\n",inet_ntoa(cin.sin_addr),\
129                 ntohs(cin.sin_port),newsfd,buf);
130 
131         //发送
132         strcat(buf,"*__*");
133         if(send(newsfd,buf,sizeof(buf),0)<0)
134         {
135             ERR_MSG("send");
136             return -1;
137         }
138         printf("发送成功\n");
139     }
140     close(newsfd);
141     return 0;
142 }
143 
144 
~                                                                                                                                                                                         

运行结果

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值