1.1 UDP编程常用函数之bind函数
UDP网络程序想要收取数据需什么条件?
#确定的IP地址
#确定的port
如何完成上面的条件?
#接收端使用bind函数,来完成地址结构与socket套接字的绑定,这样IP、port就固定了
#发送端在sendto函数中指定接收端的IP、port,就可以发送数据了
//bind 函数
int bind(int sockfd,
const struct sockaddr *myaddr, socklen_t addrlen);
/*
功能:
将本地协议地址与socket绑定
参数:
sockfd:socket套接字
myaddr:指向特定协议的地址结构指针
addrlen:改地址结构的长度
返回值:
成功:返回0
失败:其他
*/
//bind示例代码
#include <sys/socket.h>
int err_log=0
unsigned short port=8000;
struct sockaddr_in my_addr;
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(port);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
err_log=bind(sockfd, struct sockaddr*)&my_addr, sizeof(my_addr));
if(err_log!=0)
{
perror("bind");
close(sockfd);
exit(-1);
}
//注意:INADDR_ANY 通配地址,值为0
1.2 接受数据----recvfrom函数
//recvfrom函数结构
ssize_t recvfrom(int sockfd, void *buf,
size_t nbytes, int flags,
struct sockaddr *from,
socklen_t *addrlen);
/*
功能:
接受UDP数据,并将源地址信息保存在from指向的结构中
参数:
sockfd:套接字
buf:接收数据缓冲区
nbytes:接收数据缓冲区的大小
flags:套接字标志(常为0)
from:源地址结构指针,用来保存数据的来源
addrlen:from所指向内容的长度
返回值:
成功:接收到的字符数
失败:-1
*/
**bind函数程序示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(int argc, char const *argv[])
{
unsigned short port =8080;
if (argc>1)
{
port=atoi(argv[1]);//修改本程序的端口
}
int sockfd;
sockfd=socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd<0)
{
perror("socket");
exit(-1);
}
struct sockaddr_in my_addr;
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(port);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
printf("绑定服务器端口:%d\n", port);
int err_log;
err_log=bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
if (err_log!=0)
{
perror("bind");
close(sockfd);
exit(-1);
}
printf("接收数据:...\n");
while(1)
{
int recv_len;
char recv_buf[512]="";
struct sockaddr_in client_addr;
char client_ip[INET_ADDRSTRLEN]="";//INET_ADDRSTRLEN=16
socklen_t clientaddr_len=sizeof(client_addr);
recv_len=recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&client_addr, &clientaddr_len);
inet_ntop(AF_INET, &client_addr.sin_addr,client_ip,INET_ADDRSTRLEN);
printf("\nIP:%s, port:%d\n", client_ip, ntohs(client_addr.sin_port));
printf("data(%d):%s\n", recv_len, recv_buf);
}
close(sockfd);
return 0;
}
1.3 UDP编程–client、server注意点
UDP客户端注意点
1、本地IP、本地端口(我是谁)
2、目的IP、目的端口(发给谁)
3、在客户端的代码中,我们只设置了目的IP、目的端口
UDP服务端注意点
1、服务器之所以要bind,是因为它的本地port需要固定,而不是随机的
2、服务器也可以主动地给客户端发送数据
3、客户端也可以用bind函数,这样客户端的本地端口就是固定的了,但是一般不这样做。