Linux 下的udp通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21078557/article/details/53453663

话不多说,第一步:
首先在你的Linux下建立一个文件夹并创建server.c和client.c的文件。

命令:touch server.c client.c

第二步
将此服务器代码拷贝到你的server.cpp中:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define port 1234
#define maxdatasize 100
int main()
{
//定义一个套接字描述符
int sockfd;

//定义一个服务器地址结构体
struct sockaddr_in server;

//定义一个客户端的地址结构体
struct sockaddr_in client;

//定义变量用于存储struct sockaddr * 结构体的大小
socklen_t sin_size;

//用于计算接收到的字节个数
int num;

//定义接受字符数组
char msg[maxdatasize];

//定义发送数组
char sbuf[100]="";

//判断创建socket是否成功
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
perror("socket failed\n");
exit(1);
}

//bzero的作用是置字符串的前n个为空
//在头文件string.h中
//初始化server结构体
bzero(&server,sizeof(server));

//填充服务端结构体
server.sin_family=AF_INET;
server.sin_port=htons(port);
//server.sin_addr.s_addr=htonl(INADDR_ANY);
server.sin_addr.s_addr=inet_addr("10.105.235.53");
//判断绑定是否成功
if(bind(sockfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1)
{
printf("bind failed\n");
exit(1);
}
//计算struct sockaddr_in 的大小
//sin_size=sizeof(struct sockaddr_in);

//利用循环一直阻塞等待客户端发送数据
//此服务器为循环服务器
printf("init done,waiting the data comeing....\n");
while(1)
{
//一直调用recvfrom接受数据同时将接收到的字符总数存入num中
num=recvfrom(sockfd,msg,maxdatasize,0,(struct sockaddr *)&client,&sin_size);

//判断接受是否成功
if(num<0)
{
printf("recvfrom error\n");
exit(1);
}

//需要在接收到的字符数组后添加字符串标志
msg[num]='\0';
printf("收到的消息为:%s         来自: %s \n",msg,inet_ntoa(client.sin_addr));

//将接收到的数据复制到发送缓冲区
strcpy(sbuf,msg);

//发送接受到的数据
sendto(sockfd,sbuf,strlen(sbuf),0,(struct sockaddr *)&client,sin_size);

//判断是否结束本次通信
if(!strcmp(msg,"quit"))
break;
}
printf("套接字已关闭!\n");
close(sockfd);
return  0;
}

第三步:
将此客户端代码拷贝到你的client.c中:

#include <string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#define port 1234
#define maxdatasize 100
int main()
{
//sockfd 为创建的套接字序列号,用于接受成功创建后的套接字序列号
//numbytes 为用于统计recvfrom函数返回接受的字节数
int sockfd,numbytes;
//定义接受缓冲区
char buf[maxdatasize];
//定义发送缓冲区
char sendbuf[200]="hello";
//struct hosten *he;
//定义server地址结构用于填充服务器端的信息
//reply用于存放接受到数据段的相关信息
struct sockaddr_in server,reply;
//判断套接字创建是否成功
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
printf("socket fialed\n");
exit(1);
}
//初始化server结构体
bzero(&server,sizeof(server));
//填充协议族
server.sin_family=AF_INET;
//填充端口
server.sin_port=htons(port);
//填充IP地址
server.sin_addr.s_addr=inet_addr("10.105.235.53");
//调用发送函数,测试连接
sendto(sockfd,sendbuf,strlen(sendbuf),0,(sockaddr*)&server,sizeof(struct sockaddr));
//printf("sendto->errno:%d\n",errno);
//perror("socket");
//定义socklen_t 类型的长度
socklen_t len;
//计算 sockaddr_in 的大小
len=sizeof(struct sockaddr_in);
while(1)
{
//调用 recvfrom 函数,会阻塞当前等待服务器端的数据到来
//同时将正确接收到的字节数存在numbytes中
numbytes=recvfrom(sockfd,buf,maxdatasize,0,(struct sockaddr *)&reply,&len);
//判断接受是否正确
if(numbytes==-1)
{
printf("recvfrom error\n");
exit(1);
}
//判断接受到的数据是否来自设定的服务器
if(len!=sizeof(struct sockaddr)||memcmp((const void *)&server,(const void *)&reply,len)!=0)
{
printf("recive message from other server.\n");
continue;
}
//打印从服务器接受到的数据
printf("从服务器接收到的字节数为:%d\n",numbytes);
buf[numbytes]='\0';
printf("服务器发送的数据为:%s\n",buf);
printf("请输入你要发送的数据:");
//从键盘获取输入的字符串
fgets(sendbuf,sizeof(sendbuf),stdin);
//scanf("%s",&sendbuf);
sendbuf[strlen(sendbuf)-1]='\0';//去掉fgets获得的回车
int cnt=sendto(sockfd,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&server,sizeof(struct sockaddr));
printf("发送的字节数为:%d\n",cnt);
//printf("sendto errno is :%d\n",errno);
if(strcmp(sendbuf,"quit")==0)
break;
}
printf("套接字已关闭\n");
close(sockfd);
return 0;
}

第四步:

编译运行:使用如下命令

sudo gcc -o server server.c
sudo gcc -o client client.c

第五步:
赋值权限,777为所有权限都有 权限值的对应为4 2 1

chmod 777 server client

第六步:

运行程序,注意,一定要先开启服务器端,需要在两个不同的终端分别开启其中任何一个

./server   
./client

第七步:
注意 需要自己手动修改client.c 和server.c 中的对应的IP地址。

猜你喜欢

转载自blog.csdn.net/qq_21078557/article/details/53453663