UDP
无连接尽力传输,是不可靠的
send函数
send()比write多一个参数flags:
flags:
一般填写0,此时和write()作用一样
MSG_DONTWAIT:非阻塞版本
MSG_OOB:用于发送TCP类型的带外数据
recv函数
flags:一般填写0,此时和read()作用一样
MSG_DONTWAIT:非阻塞版本
MSG_OOB:用于发送TCP类型的带外数据
服务端server:
bind():绑定服务器的IP地址和端口号。
recvfrom():阻塞等待客户端数据。
do something:处理数据
sendto():返回处理结果
客户端:client
sendto():1.填写服务器的IP地址和端口号。2.要发送的数据。
server.c
int main(void)
{
int fd = -1;
struct sockaddr_in sin;
/*1.创建socket fd*/
if((fd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
/*优化2.允许绑定地址快速重用*/
int b_reuse = 1;
setsockopt(fd,SOL_SOKET,SO_REUSEADDR,&b_reuse,sizeof(int));
/*2.绑定*/
/*2.1填充struct sockaddr_in结构体变量*/
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT); //网络字节序端口号
/*2.2让服务器程序能绑定在任意IP上*/
#if 1
sin.sin_addr.s_addr = hton1(INADDR_ANY);
#else
if(inet_pton(AF_INET,SERV_IP_ADDR,(void *)&sin.sin_addr)! =1)
{
perror("inet_pton");
exit(1);
}
#endif
/2.2绑定/
if(bind(fd,(struct sockaddr *)&sin,sizeof(sin))<))
{
perror("bind");
exit(1);
}
char buf[BUFSIZ];
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
while(1){
bzero(buf,BUFSIZ);
if(recvfrom(fd,buf,BUFSIZ-1,0,(struct sockaddr *)&cin,&addrlen)<0)
{
perror("recvfrom");
continue;
}
char ipv4_addr[16];
if(!inet_ntop(AF_INET,(void *)&cin.sin_addr,ipv4_addr,sizeof(cin)))//把网络字节序的数据转换为本地数据
{
perror("inet_ntop");
exit(1);
}
printf("recived from(%s :%d)data :",ipv4_addr,ntohs(sin.sin_port),buf);
if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) //用户输入了quit字符
{
printf("client(fd+%d) is exting!\n",ipv4_addr,nthos(sin.sin_port));
}
}
close(fd);
return 0;
}
client.c
/*UDP demo*/
/*usage:
*./client serv_ip serv_port
*/
void usage(char *s)
{
printf("\nthis is udp demo!\n");
printf("\n usage:\n\t%s serv_ip serv_port",s);
printf("\n\t serv_ip:udp server ip address");
printf("\n\t serv_port:udp server port\n\n");
}
int main(int argc,char *argv[])
{
int fd = -1;
int port = SERV_PORT;
port = atoi(argv[2]);
if(port < 0 ||(port > 0 && port < 5000))
{
usage(argv[0]);
exit(1);
}
struct sockaddr_in sin;
/*1.创建socket fd*/
if(argc != 3)
{
usage(argv[0]);
exit(1);
}
/*1.创建socket fd*/
if(fd = socket(AF_INET,SOCK_DGRAM,0)<0){ //UDP编程
perror("socket");
exit(1);
}
/*2.1填充struct sockaddr_in 结构体变量*/
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT); //网络字节序端口号
/*2.2让服务器程序能绑定在任意IP上*/
#if 0
sin.sin_addr.s_addr = hton1(INADDR_ANY);
#else
if(inet_pton(AF_INET,argv[1],(void *)&sin.sin_addr)! =1)
{
perror("inet_pton");
exit(1);
}
#endif
char buf[BUFSIZ];
while(1){
bzero(buf,BUFSIZ);
if(fgets(buf,BUFSIZ-1,stdin) == NULL){
perror("fgets");
continue;
}
sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&sin,sizeof(sin));
if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) //用户输入了quit字符
{
printf("client is exited!\n");
break;
}
}
close(fd);
}