udp_server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
pthread_t SENDTO;
pthread_t RECVFROM;
#define PORT 12000
#define IP "192.168.48.130"
char buf[100];
char Buf[100];
typedef struct SERVER_INFO
{
int building;
int uint;
int room;
unsigned int IPaddr;
}INFO;
//初始化socket
void my_server(void)
{
int socketfd = -1;
int count = 0;
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
//第一步,socket得到一个UDP的fd
if((socketfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
}
//设置IP地址
int len=sizeof(serveraddr);
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET; //IP地址类型为IPv4
serveraddr.sin_port=htons(PORT); //端口号
serveraddr.sin_addr.s_addr=inet_addr(IP);//绑定IP
//第二步,bind服务器的IP
if((bind(socketfd,(const struct sockaddr *)&serveraddr,sizeof(serveraddr)))<0)
{
perror("bind");
}
else
{
printf("bind had success!\n");
}
while(1)
{
recvfrom(socketfd,buf,sizeof(buf),0,(struct sockaddr *)&clientaddr,&len);
if(memcmp(buf,"end",3)==0)
{
break;
}
else
{
printf("服务器接收client发过来 %d 字节\n",strlen(buf));
printf("接收的内容:%s \n",buf);
memset(buf,0,sizeof(buf));
}
fgets(buf,20,stdin);//非阻塞式标准输入
sendto(socketfd,buf,sizeof(buf),0,(const struct sockaddr *)&clientaddr,len);
printf("服务器发送给客户端的数据 :%s\n",Buf);
}
return;
}
int main(void)
{
my_server();
return 0;
}
udp_client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 12000
#define IP "192.168.48.130"
pthread_t SENDTO;
pthread_t RECVFROM;
char buf[20];
char Buf[20];
void my_client(void)
{
int socketfd = -1;
int len=0;
int count=0;
struct sockaddr_in serveraddr;
struct sockaddr_in connectaddr;
len=sizeof(connectaddr);
//第一步,socket得到一个UDP的fd
if((socketfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
}
//设置IP地址(IP为要连接的服务器地址)
bzero(&connectaddr,sizeof(connectaddr));
connectaddr.sin_family=AF_INET;
connectaddr.sin_port=htons(PORT);
connectaddr.sin_addr.s_addr=inet_addr(IP);
while(1)
{
fgets(buf,20,stdin);
//客户端向服务端发送
{
sendto(socketfd,buf,sizeof(buf),0,(const struct sockaddr *)&connectaddr,len);
printf("客户端发送给服务器的数据 :%s\n",buf);
if(memcmp(buf,"end",3)==0)
{
break;
}
//printf("buf=%s\n",buf);
memset(buf,0,sizeof(buf));
}
count=recvfrom(socketfd,Buf,sizeof(buf),0,(struct sockaddr *)&serveraddr,&len);
printf("客户端接收服务器发过来 %d 字节\n",strlen(Buf));
printf("接收的内容:%s \n",Buf);
}
return;
}
int main(void)
{
my_client();
return 0;
}
Makefile
all:
gcc udp_server.c -o server -pthread
gcc udp_client.c -o clinet -pthread
clean:
rm server clinet *.o -rf
make执行编译,打开两个终端分别执行./server ./client的结果如下
实现功能:实现了UDP通信基本要求,半双工模式。UDP与TCP比较缺少了connect,listen,accept等复杂步骤。这里要使用fgets标准输入,这是非阻塞的,在没有数据从键盘输入待发送时,不会阻塞住主线程,所以可以一直在循环中运行。如果使用scanf输入的话,因为这个函数为堵塞式,会增加编程麻烦。