网络编程 UDP编程 Linux环境 C语言实现
UDP编程
1. 一般UDP编程
UDP传输特点:非面向连接、不可靠的、无序的 报式传输 支持组播和广播
UDP应用数据最大长度建议:MTU(以太网分组数据的最大长度)1500 - 20(IP头) - 8(UDP头) = 1472Bytes
客户端:支持两种形式的代码编写:
1. 不定向传输
2. 定向传输 ------ 只与指定的服务端进行UDP数据交互
新函数:
2. IP地址分类
以下特殊IP地址去除掉:
- IP地址4个字节全0
- IP地址4个字节全1
- ABC三类IP地址中主机号全0
- ABC三类IP地址中主机号全1
- A类中127.开头的IP地址
剩余的A、B、C三类IP地址,才能作为因特网上的某台主机的IP地址用,这些IP地址再被分为两大类:
1. 用于边缘网络:A类的10.x.x.x B类的172.16.x.x C类的192.168.0.x ~ 192.168.255.x
2. 用于核心网络:剩余的才能作为核心网上主机的IP地址用
3. UDP广播
或
4. UDP组播
本地Socket
采用带路径的socket文件名作为服务端进程的身份标识:
专用socket地址结构体:
struct sockaddr_un{
sa_family_t sun_family;//固定为AF_UNIX 或 AF_LOCAL
char sun_path[108];
};
socket函数的第一个参数传AF_UNIX 或 AF_LOCAL
其它接口使用同TCP
示例代码:
send.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[]){
int sockfd = -1;
struct sockaddr_in servaddr;
int on = 1;
/*1. 为了后续的UDP传输创建一个引擎对象,并获得该引擎对象的描述符*/
sockfd = socket(AF_INET,SOCK_DGRAM,0);
/*2. 允许使用指定socket描述符发送广播数据*/
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
/*3. 填写目标网络的广播地址和端口号*/
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9898);
//inet_aton("255.255.255.255",&servaddr.sin_addr);
inet_aton("172.16.181.128",&servaddr.sin_addr);
/*3.发送广播数据*/
sendto(sockfd,"hello",6,0,(struct sockaddr *)&servaddr,sizeof(servaddr));
/*4. 无需继续发送广播数据时,及时关闭描述符*/
close(sockfd);
sockfd = -1;
return 0;
}
recv.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[]){
int sockfd = -1;
struct sockaddr_in servaddr;
int ret = 0;
/*1. 为了后续的UDP传输创建一个引擎对象,并获得该引擎对象的描述符*/
sockfd = socket(AF_INET,SOCK_DGRAM,0);
/*2. 填写服务端的IP和端口号*/
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9898);
//inet_aton("0.0.0.0",&servaddr.sin_addr);
inet_aton("172.16.181.128",&servaddr.sin_addr);
/*3. 为服务端UDP socket引擎对象指定IP地址和端口号*/
ret = bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
if(ret){
printf("In Server,bind failed\n");
close(sockfd);
sockfd = -1;
return 1;
}
/*4. 接收广播数据*/
{
char buf[8] = "";
struct sockaddr_in cliaddr;
socklen_t socklen = sizeof(cliaddr);
recvfrom(sockfd,buf,8,0,(struct sockaddr *)&cliaddr,&socklen);
printf("In Server,buf=%s\n",buf);
printf("In Server,client port = %d\n",cliaddr.sin_port);
printf("In Server,client ip = %s\n",inet_ntoa(cliaddr.sin_addr));
}
/*5. 无需继续接收广播数据时,及时关闭描述符*/
close(sockfd);
sockfd = -1;
return 0;
}
p.s. aton中 " 172.16.181.128 " 是从 ifconfig 命令中获取
输出:
先运行 recv.c
新建标签页,运行 send.c