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
~
运行结果