利用UDP协议与socket文件完成两个进程之间的网络通信,这里分为服务端与客户端,服务端则是在云端运行的服务器进程,客户端则为计算机本地运行的进程。
服务器
头文件
首先是服务器里面各种头文件:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
宏
这里还定义了一个宏,强制类型转换:
typedef struct sockaddr* SP;
创建服务器的socket文件
首先是创建服务器的socket文件,其中AF_INET为基本32IP地址通信,IPv4版本,若创建失败则返回失败原因
int main()
{
printf("创建socket...\n");
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(0 > sockfd)
{
perror("socket");
}
准备地址
然后是准备地址,注意端口号要与客户端的端口号一值,IP地址则是服务器的私网IP地址。
printf("准备地址...\n");
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(7887);
addr.sin_addr.s_addr = inet_addr("172.16.27.135");
socklen_t len = sizeof(addr);
绑定socket与地址
利用bind函数绑定socket文件与函数,失败则打印失败原因
printf("绑定socket与地址\n");
if(bind(sockfd,(SP)&addr,len))
{
perror("bind");
return -1;
}
接收请求与响应请求
创建一个死循环,不断接收消息并且答应出来以及消息来源的IP,然后不断反馈给终端,当收到quit则通信结束。
struct sockaddr_in addrcli = {};
char buf[1024] = {};
for(;;)
{
//接收请求
int ret = recvfrom(sockfd,buf,sizeof(buf),0,(SP)&addrcli,&len);
printf("recv:%s,ip:%s,port:%hu,size:%d\n",buf,inet_ntoa(addrcli.sin_addr),addrcli.sin_port,ret);
if(0 == strcmp("quit",buf))
{
printf("通信结束!\n");
break;
}
//响应请求
sendto(sockfd,buf,strlen(buf)+1,0,(SP)&addrcli,len);
}
关闭socket文件
最后关闭socket文件
close(sockfd);
以下则是客户端:
客户端
头文件、与socket文件创建、准备地址
头文件、与socket文件创建和准备地址与服务器的程序代码差不多,除了ip地址需要填写的是服务器的公网ip地址。
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <arpa/inet.h>
7 #include <netinet/in.h>
8
9 typedef struct sockaddr* SP;
10
11 int main()
12 {
13 printf("创建socket...\n");
14 int sockfd = socket(AF_INET,SOCK_DGRAM,0);
15 if(0 > sockfd)
16 {
17 perror("socket");
18 }
19
20 printf("准备地址...\n");
21 struct sockaddr_in addr = {};
22 addr.sin_family = AF_INET;
23 addr.sin_port = htons(7887);
24 addr.sin_addr.s_addr = inet_addr("47.96.239.112");
发送请求并且接收响应
不断输入字符串,发送给服务器,发送什么服务器就会返回什么并且附上IP地址,当输入quit则通信结束
27 socklen_t len = sizeof(addr);
28 struct sockaddr_in addrcli = {};
29 char buf[1024] = {};
30 for(;;)
31 {
32 //发送请求
33 printf(">");
34 gets(buf);
35 int ret = sendto(sockfd,buf,strlen(buf)+1,0,(SP)&addr,len);
36 if(0 == strcmp("quit",buf))
37 {
38 printf("通信结束!\n");
39 break;
40 }
41 //接收响应
42 recvfrom(sockfd,buf,sizeof(buf),0,(SP)&addrcli,&len);
43 printf("recv:%s,ip:%s,port:%hu,size:%d\n",buf,inet_ntoa(addrcli.sin_addr),addrcli.sin_port,ret);
44 }
关闭socket文件
最后关闭socket文件
45 //关闭socket
46 close(sockfd);
47 }
以下则是程序运行效果,左边是云端服务器,右边则是本地终端。