基於UDP的保持相互通訊例項
阿新 • • 發佈:2018-12-19
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輸入的話,因為這個函式為堵塞式,會增加程式設計麻煩。