udp通信流程代码实现客户端和服务器的连接
原理流程:
函数使用:
//接收数据
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
参数: int sockfd 套接字描述符
void *buf 存储接收的数据
size_t len 存储数据的空间大小
int flags 标志设置为0
struct sockaddr *src_addr,存储数据发送方地址
socklen_t *addrlen存储发送方地址的长度
返回值:返回接收的字节数, 失败-1
//反馈数据
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
参数: int sockfd 套接字描述符
const void *buf 要发送的数据
size_t len 发送数据的长度
int flags 标志设置为0
struct sockaddr * dest_addr 目标地址
socklen_t addrlen地址长度
返回值:返回发送的字节数, 失败-1
实现的完整代码如下:
//发送方:客户端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
//1.创建套接字UDP--SOCK_DGRAM
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket fail");
return -1;
}
//2.发送数据
struct sockaddr_in destAddr; //定一个存储地址,端口号的替代结构体
memset(&destAddr, 0, sizeof(destAddr)); //初始化为0
destAddr.sin_family = AF_INET;//初始化地址族IPV4
destAddr.sin_port = htons(8999); //设置端口号(网络字节序号)
destAddr.sin_addr.s_addr = inet_addr("192.168.24.21");//发给谁谁谁
char sendbuffer[]="hello world"; //发送端要保存服务器的地址
ssize_t size = sendto(sockfd, sendbuffer, sizeof(sendbuffer), 0, (struct sockaddr*)&destAddr, sizeof(destAddr));
if(size <0){
perror("sendto error");
close(sockfd);
return -1;
}
//接收反馈数据
char recvbuffer[1024];
size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, NULL, NULL);
if(size < 0)
{
perror("recvfrom error");
return -1;
}
printf("%s\n", recvbuffer);
close(sockfd);
}
//接收方:服务器
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdbool.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#define MAXSIZE 100
int main(void)
{
//1.创建套接字 UDP--SOCK_DGRAM
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket fail");
return -1;
}
//设置地址复用
int on = 1;
int ropt = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
//初始化
struct sockaddr_in addr; //定一个存储地址,端口号的替代结构体
memset(&addr, 0, sizeof(addr)); //初始化为0
addr.sin_family = AF_INET;//初始化地址族IPV4
addr.sin_port = htons(8999); //设置端口号(网络字节序号)
addr.sin_addr.s_addr = INADDR_ANY;//初始化绑定地址, 用INADDR_ANY--表示绑定本机地址
//2.绑定
int ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
if(ret < 0)
{
perror("bind fail:");
return -1;
}
//3.接收数据
struct sockaddr_in srcAddr;//保存发送方的地址
socklen_t len = sizeof(srcAddr);
char recvbuffer[1024]; //服务器要保存发过来的客户地址
ssize_t size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, (struct sockaddr*)&srcAddr, &len);
if(size < 0)
{
perror("recvfrom error");
return -1;
}
printf("%s\n", recvbuffer);
//反馈数据给发送端
strcat(recvbuffer, "这里是我收到的数据反馈");
size = sendto(sockfd, recvbuffer, sizeof(recvbuffer), 0, (struct sockaddr*)&srcAddr, len);
//关闭套接字
close(sockfd);
return 0;
}
实现结果:收发数据点对点通信效果,一段发数据,一段收数据并反馈接一段数据