UDP运行模式如图:
udp收发消息讲解:点击打开链接
程序运行效果如下:
服务端:
客户端:
服务端原码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/*
绑定套接字后,一直处于recvfrom阻塞状态, 直到有客户端连接
输入 读取EOF后关闭服务器 */
#define PORT 3333
void main()
{
printf("程序开始\n");
int sockfd; //套接字描述符
struct sockaddr_in s_addr; //服务器地址结构
struct sockaddr_in c_addr; //客户端地址结构
socklen_t addr_len; //地址结构长度
int len; //接收到消息的字节数
char buff[BUFSIZ]; //消息缓冲区
int firstFlag = 1; //第一次接入
/********************创建套接字***************/
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if( sockfd < 0 ){
perror("创建套接字失败");
exit(EXIT_FAILURE);
}
printf("套接字创建成功\n\r");
/******************清空地址结构**************/
memset(&s_addr,0,sizeof(struct sockaddr_in));
/*****************设置端口和地址信息***********/
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/***************绑定地址和端口***********/
if(bind(sockfd,(struct sockaddr*)&s_addr,sizeof(s_addr)) < 0){
perror("绑定地址失败");
exit(EXIT_FAILURE);
}
printf("绑定地址成功\n\r");
/***************循环接收数据************/
addr_len =sizeof(c_addr);
while(1){
printf("等待连接...\n");
//fflush(stdin)刷新标准输入缓冲区,fflush(stdout)刷新标准输出缓冲区
fflush(stdout);
/********************recvfrom接收数据*********************/
//参数:
// sockfd:套接字
// buf: 接收数据缓冲区
// nbytes:接收数据缓冲区的大小
// flags: 套接字标志(常为0)
// from: 用于存放发送方信息的地址结构体指针
// addrlen: from所指内容的长度
//返回值:成功:接收到的字符数;失败: -1
len = recvfrom(sockfd,buff,sizeof(buff)-1,0,(struct sockaddr*)&c_addr,&addr_len);
if(len < 0){
perror("接收失败");
//exit(EXIT_FAILURE);
}else{
printf("\n新数据:\n");
buff[len] = '\0';
printf("IP is %s\n",inet_ntoa(c_addr.sin_addr));
printf("port %d\n",ntohs(c_addr.sin_port));
printf("msg is %s\n",buff);
}
//EOF,断开连接
if(strncmp(buff,"EOF",3) == 0){
break;
}
/********************sendto用于发送数据请求****************/
//参数:
// sockfd:套接字
// buf:发送数据缓冲区
// nbytes:发送数据缓冲区的大小
// flags:一般为0
// to:指向目的主机地址结构体的指针
// addrlen:to所指向内容的长度
//返回值:成功:发送的字符数;失败: -1
printf("\n请输入:");
fflush(stdout);
scanf("%s",buff);
len = sendto(sockfd,buff,sizeof(buff)+1,0,(struct sockaddr*)&c_addr,addr_len);
if(len < 0){
perror("发送失败");
//exit(EXIT_FAILURE);
}else
printf("发送成功\n");
//EOF,断开连接
if(strncmp(buff,"EOF",3) == 0){
break;
}
}//while
close(sockfd);
printf("程序结束\n");
return;
}
客户端原码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/*
连接到服务器后,会不停循环,等待输入,
输入 读取EOF后断开连接并关闭客户端*/
#define PORT 3333
void main()
{
printf("程序开始\n");
int sockfd; //套接字描述符
struct sockaddr_in s_addr; //套接字地址结构
socklen_t addr_len; //地址结构长度
int len; //接收到消息的字节数
char buff[BUFSIZ]; //消息缓冲区
/********************创建套接字***************/
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if( sockfd < 0 ){
perror("创建套接字失败");
exit(EXIT_FAILURE);
}
printf("套接字创建成功\n\r");
/******************清空地址结构**************/
memset(&s_addr,0,sizeof(struct sockaddr_in));
/**************设置服务器端口和地址信息***********/
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
/***************循环接收数据************/
addr_len =sizeof(s_addr);
while(1){
/********************sendto用于发送数据请求****************/
printf("\n请输入:");
fflush(stdout);
scanf("%s",buff);
len = sendto(sockfd,buff,sizeof(buff)+1,0,(struct sockaddr*)&s_addr,addr_len);
if(len < 0){
perror("发送失败");
//exit(EXIT_FAILURE);
}else
printf("发送成功\n");
//EOF,断开连接
if(strncmp(buff,"EOF",3) == 0){
break;
}
/********************recvfrom接收数据*********************/
len = recvfrom(sockfd,buff,sizeof(buff)-1,0,(struct sockaddr*)&s_addr,&addr_len);
if(len < 0){
perror("接收失败");
//exit(EXIT_FAILURE);
}else{
printf("\n新数据:\n");
buff[len] = '\0';
printf("IP is %s\n",inet_ntoa(s_addr.sin_addr));
printf("port %d\n",ntohs(s_addr.sin_port));
printf("msg is %s\n",buff);
}
//EOF,断开连接
if(strncmp(buff,"EOF",3) == 0){
break;
}
}
close(sockfd);
printf("程序结束\n");
return;
}