一 、UDP基本概念
- udp :是不可靠传输,无连接的尽力传输;
二、UDP编程 API
1、发送api
- ssize_t send(int sockfd ,const void* buf , size_t len ,int flags);
- ssize_t sendto (int sockfd , const void * buf ,size_t len ,int flags , const struct sockaddr* dest_addr,socklen_t addrlen);
— const struct sockaddr* dest_addr : 对方的IP地址+端口
— socklen_t addrlen : 地址的长度
1、接收api
- ssize_t recv (int sockfd ,void* buf , size_t len ,int flags);
- ssize_t recvfrom (int sockfd , void * buf ,size_t len ,int flags , struct sockaddr* dest_addr,socklen_t * addrlen);
— struct sockaddr* dest_addr : 对方的IP地址+端口
— socklen_t addrlen : 地址长度变量的地址;
三、UDP编程示例
1、服务器 源码
#include "net_udp.h"
int main(int argc, const char *argv[])
{
int fd = -1;
struct sockaddr_in sin;
/*1、创建socket fd*/
if((fd = socket(AF_INET , SOCK_DGRAM , 0)) < 0){
perror("socket");
exit(1);
}
/*优化1 : 允许客户端快速重连*/
int b_reuse = -1;
char server_ip[16];
setsockopt(fd , SOL_SOCKET, SO_REUSEADDR , &b_reuse , sizeof(int));
/*2 、绑定*/
/*2.1 填充*/
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY :为0.0.0.0 泛指本机的意思
/*2.2 绑定*/
if(bind(fd , (struct sockaddr*)&sin, sizeof(sin))){
perror("bind");
exit(1);
}
if(!inet_ntop(AF_INET , (void*)&sin.sin_addr,server_ip,sizeof(sin))){
perror("inet_ntop");
exit(1);
}
printf("Server %s starting......\n",server_ip);
/*3、*/
char buff[BUFSIZ];
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
while(1){
bzero(buff, sizeof(buff));
if(recvfrom(fd , buff , BUFSIZ-1 , 0 ,(struct sockaddr*)&cin ,&addrlen) < 0){
perror("recvform");
continue;
}
char ipv4_addr[16];
if(!inet_ntop(AF_INET , (void*)&cin.sin_addr,ipv4_addr,sizeof(cin))){
perror("inet_ntop");
exit(1);
}
printf("Client (%s:%d) Send : %s \n",ipv4_addr,htons(sin.sin_port) ,buff);
if(!strncasecmp(buff,"quit\n",sizeof("quit\n"))){
printf("Client (%s : %d) is exiting \n",ipv4_addr , htons(sin.sin_port));
}
}
close(fd);
return 0;
}
2、客户端 源码
#include "net_udp.h"
void usage(const char* s){
printf("\n %s serv_ip ser_port \n",s);
printf("\n\t serv_ip:server ip address");
printf("\r\n serv_port: server port(>5000)\n");
}
int main(int argc, const char *argv[])
{
int fd = -1;
int port = 0;
struct sockaddr_in sin;
if((fd = socket(AF_INET , SOCK_DGRAM,0)) < 0 ){
perror("socket");
exit(1);
}
if(argc != 3 ){
usage(argv[0]);
exit(1);
}
port = atoi(argv[2]);
if (port < 5000){
usage(argv[0]);
exit(1);
}
/*2、填充*/
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT);
if( inet_pton(AF_INET,argv[1],(void*)&sin.sin_addr) != 1){
perror("inet_ntop");
exit(1);
}
printf("Client starting ....... \n");
char buff[BUFSIZ];
while(1){
bzero(buff,BUFSIZ);
if(fgets(buff,BUFSIZ-1,stdin) == NULL){
perror("fgets");
continue;
}
sendto(fd,buff,strlen(buff),0,(struct sockaddr*)&sin,sizeof(sin));
if(!strncasecmp(buff , "quit\n",sizeof("quit\n"))){
printf("Client is exiting !!! \n");
break;
}
}
close(fd);
return 0;
}
3、所用头文件 以及宏
#ifndef __NET_UDP_H__
#define __NET_UDP_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <error.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#define SERV_PORT 5001
#define SERV_IP_ADDR "192.168.196.132"
#define BACKLOG 5
#define QUIT_STR "quit"
#endif