一.Linux下UDP编程框架
使用UDP进行程序设计可以分为客户端和服务器端两部分。
1.服务器端程序包括:
Ø
Ø
Ø
Ø
2.客户端程序包括:
Ø
Ø
Ø
3.服务器端和客户端程序之间的差别
服务器端和客户端两个流程之间的主要差别在于对地址的绑定函数(bind()函数),而客户端可以不用进行地址和端口的绑定操作。
二.Linux中UDP套接字函数
网络程序通过调用socket()函数,会返回一个用于通信的套接字描述符。Linux应用程序在执行任何形式的I/O操作的时候,程序是在读或者写一个文件描述符。因此,可以把创建的套接字描述符看成普通的描述符来操作,并通过读写套接字描述符来实现网络之间的数据交流。
1.
1>
int socket(intdomain,int type,int protocol)
2>
函数socket()用于创建一个套接字描述符。
3>
Ø
中定义。
常见的协议族如下:
AF_UNIX:创建只在本机内进行通信的套接字。
AF_INET:使用IPv4TCP/IP协议
AF_INET6:使用IPv6TCP/IP协议
说明:
AF_UNIX只能用于单一的UNIX系统进程间通信,而AF_INET是针对Interne的,因而可以允许在远程主机之间通信。一般把它赋为AF_INET。
Ø
SOCK_STREAM:创建TCP流套接字
SOCK_DGRAM:创建UDP数据报套接字
SOCK_RAW:创建原始套接字
Ø
参数protocol通常设置为0,表示通过参数domain指定的协议族和参数type指定的套接字类型来确定使用的协议。当为原始套接字时,系统无法唯一的确定协议,此时就需要使用使用该参数指定所使用的协议。
4>
5>
int sock_fd;
sock_fd =socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd < 0){
}
2.
1>
int bind(intsockfd,struct sockaddr *my_addr,socklen_taddrlen)
2>
函数bind()的作用是将一个套接字文件描述符与一个本地地址绑定在一起。
3>
Ø
Ø
Ø
4>
(1)structsockaddr:
结构struct
Linux/socket.h 中定义。
struct sockaddr{
}
a.
b.
(2)sockaddr_in
每种协议族都有自己的协议地址格式,TCP/IP协议组的地址格式为结构体structsockaddr_in,它在netinet/in.h头文件中定义。
struct sockaddr_in{
}
a.
b.
c.
d.
e.
struct in_addr{
}
结构体sockaddr的长度为16字节,结构体sockaddr_in的长度为16字节。可以将参数my_addr的sin_addr设置为INADDR_ANY而不是某个确定的IP地址就可以绑定到任何网络接口。对于只有一IP地址的计算机,INADDR_ANY对应的就是它的IP地址;对于多宿主主机(拥有多个网卡),INADDR_ANY表示本服务器程序将处理来自所有网络接口上相应端口的连接请求
5>
函数成功后返回0,当有错误发生时则返回-1,错误代码存入errno中。
6>举例:调用socket函数创建一个UDP套接字
struct sockaddr_inaddr_serv,addr_client;
memset(&serv_addr,0,sizeof(structsockaddr_in));
addr_serv.sin_family = AF_INET;
addr_serv.sin_port =htons(SERV_PORT);
addr_serv.sin_addr.s_addr =htonl(INADDR_ANY);
if(bind(sock_fd,(struct sockaddr*)&addr_serv),sizeof(structsockaddr_in))<0)
{
}
3.close
1>函数原型:
int
2>函数功能:
函数close用来关闭一个套接字描述符。
3>函数形参:
Ø
4>返回值:
执行成功返回0,出错则返回-1.错误代码存入errno中。
说明:
以上三个函数中,前两个要包含头文件
#include
#include
后一个包含:
#include
4.sendto
1>函数原型:
#include
#include
ssize_t sendo(ints,const void *msg,size_t len,intflags,const struct sockaddr *to,socklen_ttolen);
2>函数功能:
向目标主机发送消息
3>函数形参:
Ø
Ø
Ø
Ø
(1)MSG_OOB:在指定的套接字上发送带外数据(out-of-banddata),该类型的套接字必须支持带外数据(eg:SOCK_STREAM).
(2)MSG_DONTROUTE:通过最直接的路径发送数据,而忽略下层协议的路由设置。
Ø
Ø
4>函数返回值:
执行成功后返回实际发送数据的字节数,出错返回-1,错误代码存入errno中。
5>函数举例:
char
struct
memset(&addr_client,0,sizeof(structsockaddr_in));
addr_client.sin_family =AF_INET;
addr_client.sin_port =htons(DEST_PORT);
if(inet_aton(“172.17.242.131”,&addr_client.sin_addr)<0){
}
if(sendto(sock_fd,send_buf,len,0,(strutsockaddr*)&addr_client,sizeof(struct sockaddr_in))<0){
exit(1);
}
5.recvfrom
1>函数原型:
#include
#include
ssize_trecvfrom(int s,void *buf,size_t len,intflags,struct sockaddr*from,socklen_t *fromlen);
2>函数功能:接收数据
3>函数形参:
Ø
Ø
Ø
Ø
(1)MSG_OOB:请求接收带外数据
(2)MSG_PEEK:只查看数据而不读出
(3)MSG_WAITALL:只在接收缓冲区时才返回。
Ø
Ø
4>函数返回值:
执行成功后返回实际接收到数据的字节数,出错时则返回-1,错误代码存入errno中。
5>函数实例:
charrecv_buf[BUFFERSIZE];
structsockaddr_in addr_client;
int
src_len =sizeof(struct sockaddr_in);
intsrc_len;
src_len =sizeof(struct sockaddr_in);
if(recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(structsockaddr*)&src_addr,&src_len)<0){
}
三.UDP编程实例
1.服务器端程序
2.客户端程序
要想把ip地址和端口号通过main函数的参数传进去也行,比如,程序名字是udp,ip地址是192.168.0.2
文章来自:http://blog.sina.com.cn/s/blog_a87c8f5e0101le8v.html