UDP通信
通信流程如图
UDP服务端的工作流程:
1、创建--socket套接字
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain, int type, int option);
domain -- 网络协议 AF_INET(ipv)
type--数据传输方式 SOCK_STREAM (面向连接) SOCK_DGRAM(面向无连接)
option--协议类型,0
成功返回socket句柄, 失败返回-1
2、绑定--将创建的socket套接字返回的句柄与本机的ip、端口绑定
#include<sys/types.h>
#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd -- 要绑定的socket句柄
3、发送--向指定ip、端口(客户端)发送数据(接收)
#include<sys/types.h>
#include<sys/socket.h>
int sendto(int s, const void *msg, size_t len, int flags, const strcuct sockaddr *to, socklen_t tolen);
s--指定套接字句柄
msg--发送数据的缓冲首地址
len--缓冲大小
flags---0
to -- 接收数据的ip port
tolen -- sockaddr结构大小
成功返回发送数据的字节数,失败返回-1
int recvfrom(int s, void * buf, size_t len, int flag, struct sockaddr * from, socklen_t *fromlen);
s--指定套接字句柄
buf -- 接收数据的缓冲区首地址
len -- 缓冲区的最大长度
flag -- 0
from -- 发送方的 sockaddr 类型的 ip port结构体
fromlen-- from的大小
4、关闭--关闭socket
close(int s);
客户端流程:
1、创建--socket套接字
2、发送(接收)--向指定ip、端口
3、关闭socket
代码:
/**
UDP服务端的工作流程:
1、创建--socket套接字
2、绑定--将创建的socket套接字返回的句柄与本机的ip、端口绑定
3、发送--向指定ip、端口(客户端)发送数据(接收)
4、关闭--关闭socket
**/
//服务器端
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<unistd.h>
#define PORT 9090
#define DATA_SIZE 256
int main()
{
int sock_fd;
struct sockaddr_in local;
struct sockaddr_in from;
int res;
int num;
socklen_t fromlen;
char buf[DATA_SIZE];
time_t cur_time;
// 1
sock_fd = socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd == -1)
{
perror("creat socket error!\n");
return 0;
}
printf("creat socket ok\n");
//设置要绑定的IP和端口
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
local.sin_addr.s_addr=INADDR_ANY;
// 2
res = bind(sock_fd,(struct sockaddr*)&local,sizeof(local)); //成功返回0 ,失败返回-1
if(res != 0 )
{
perror("bind socket error!\n");
close(sock_fd);
return 0;
}
printf("bind socket ok\n");
fromlen = sizeof(from);
printf("wait request from client.....\n");
while(1)
{
//3 接收
num = recvfrom(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&from,&fromlen); //成功返回接收到的字符数,否则为 -1
if(num == -1)
{
perror("recv data error\n");
close(sock_fd);
return 0;
}
buf[num] = '\0'; //添加结束符
printf("client request: %s\n",buf);
if(strncmp(buf,"quit",4) == 0)
{
break;
}
if(strncmp(buf,"time",4) == 0)
{
cur_time = time(NULL);
strcpy(buf,asctime((gmtime(&cur_time))));
//发送
sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&from,fromlen);
}
}
close(sock_fd);
return 0;
}
//UDP 客户端
/**
流程:
1、创建--socket套接字
2、发送(接收)--向指定ip、端口
3、关闭socket
**/
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<unistd.h>
#define PORT 9090
#define DATA_SIZE 256
int main()
{
int sock_fd;
struct sockaddr_in serv;
int num;
socklen_t serlen;
char buf[DATA_SIZE];
//1
sock_fd = socket(AF_INET,SOCK_DGRAM,0);
//设置服务器ip和端口
serv.sin_family=AF_INET;
serv.sin_addr.s_addr=INADDR_ANY;
serv.sin_port = htons(PORT);
serlen = sizeof(serv);
strcpy(buf,"time");
//发送--向指定ip、端口
num = sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&serv,serlen);
if(num==-1)
{
perror("send error\n");
close(sock_fd);
return 0;
}
printf("send request to server\n");
//接收)
num = recvfrom(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&serv,&serlen);
if(num <= 0)
{
perror("recv data error\n");
close(sock_fd);
return 0;
}
buf[num]='\0';
printf("time from server:%s",buf);
//发送结束
strcpy(buf,"quit");
//发送--向指定ip、端口
num = sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&serv,serlen);
if(num==-1)
{
perror("send error\n");
close(sock_fd);
return 0;
}
printf("send quit to server\n");
close(sock_fd);
return 0;
}