1. UDP的特点
UDP服务器在调用bind()函数之后就可以接受任何UDP客户端发来的数据,不需要像TCP一样建立一对一连接,UDP是面向无连接的。
1)sendto()函数,调用者为发送方
头文件:#include <sys/types.h>
#include <sys/socket.h>
函数原型:ssize_t sendto(int sockfd, const void*buf, size_t len, int flags,
const struct sockaddr*dest_addr, socklen_t addrlen);
功能:向dest_addr 表示的接收方发送数据,该函数不是阻塞的,
const struct sockaddr *dest_addr 接收方的ip+port
2)recvfrom() 函数,调用者为接收方
#include <sys/socket.h>
函数原型:ssize_t recvfrom(intsockfd, void *buf, size_t len, int flags, structsockaddr *src_addr, socklen_t *addrlen);
struct sockaddr *src_addr 发送方的 ip+port
示例代码:
Client.c文件代码
/*************************************************************************
@Author: wanghao
@Created Time : Fri 25 May 2018 08:09:19 PM PDT
@File Name: client.c
@Description:
************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#define N 36
#define MAXSIZE 36
void *func(void *arg)
{
intsocketfd;
intaddrlen;
structsockaddr_in server_addr;
charbufread[MAXSIZE] = {0};
socketfd= *(int *)arg;
addrlen= sizeof(struct sockaddr);
while(1)
{
recvfrom(socketfd, bufread, sizeof(bufread), 0, (struct sockaddr*)(&server_addr), &addrlen);
printf("server ip = %s port =%d\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
printf("%s\n",bufread);
}
}
int main(int argc, const char *argv[])
{
intsocketfd;
intclient_fd;
intaddrlen;
u_shortport;
pthread_ta_thread;
charbufwrite[MAXSIZE] = "hello every!";
structsockaddr_in server_addr;
structsockaddr_in client_addr;
if(argc< 3)
{
printf("usage:%s <IPadd> <Port>\n",argv[0]);
return-1;
}
socketfd= socket(PF_INET, SOCK_DGRAM, 0);
if(socket< 0)
{
perror("");
return-1;
}
port= (u_short)atol(argv[2]);
server_addr.sin_family= PF_INET;
server_addr.sin_port= htons(port);
server_addr.sin_addr.s_addr= inet_addr(argv[1]);
addrlen= sizeof(struct sockaddr_in);
pthread_create(&a_thread,NULL, func, (void *)(&socketfd));
while(1)
{
/*Thisfunction is a non-blocking function*/
sendto(socketfd,bufwrite, sizeof(bufwrite), 0, (struct sockaddr*)(&server_addr), addrlen);
sleep(1);
}
close(socketfd);
return0;
}
Server.c文件代码:
/*************************************************************************
@Author: wanghao
@Created Time : Fri 25 May 2018 08:09:19 PM PDT
@File Name: server.c
@Description:
************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#define N 36
#define MAXSIZE 128
typedef struct client_mem
{
intflags;
structsockaddr_in client_addr;
}Client_mem;
int main(int argc, const char *argv[])
{
intsocketfd;
intclient_fd;
intaddrlen;
intflag;
u_shortport;
pthread_ta_thread;
charbuf[MAXSIZE] = {0};
structsockaddr_in my_addr;
structsockaddr_in client_addr;
if(argc< 3)
{
printf("usage:%s <IPadd> <Port>\n",argv[0]);
return-1;
}
socketfd= socket(PF_INET, SOCK_DGRAM, 0);
if(socket< 0)
{
perror("");
return-1;
}
port= (u_short)atol(argv[2]);
my_addr.sin_family= PF_INET;
my_addr.sin_port= htons(port);
my_addr.sin_addr.s_addr= inet_addr(argv[1]);
addrlen= sizeof(struct sockaddr_in);
if(bind(socketfd,(struct sockaddr *)(&my_addr), addrlen) < 0)
{
perror("");
return-2;
}
while(1)
{
if(recvfrom(socketfd,buf, sizeof(buf), 0, (struct sockaddr*)(&client_addr), &addrlen) <0)
{
perror("receiveerror!\n");
sleep(2);
continue;
}
buf[strlen(buf)]= '\0';
printf("clientip = %s port = %d\n", inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
printf("%s",buf);
if(sendto(socketfd,buf, sizeof(buf), 0, (struct sockaddr*)(&client_addr), addrlen) < 0)
{
perror("sendtoerror");
}
}
close(socketfd);
return0;
}