UNIX网络编程笔记(7):回射程序的UDP版本
生活随笔
收集整理的這篇文章主要介紹了
UNIX网络编程笔记(7):回射程序的UDP版本
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、UDP簡介
UDP是一個簡單的傳輸層協議,應用進程往一個UDP套接字寫入數據,隨后被封裝到一個UDP數據報,進而又被封裝到一個IP數據報,然后發送到目的地。UDP不保證UDP數據報會最終到達目的地,不保證各個數據報的先后順序跨網絡后保持不變,也不保證每個數據報只會到達一次,因為UDP提供無連接、無可靠性的服務。
另一個與TCP不同的是,UDP數據報中包含一個長度,如果數據報被正確送達目的地,那么該數據報的長度隨數據一起送達給對端應用程序。
下圖是典型的UDP程序的函數調用過程:
由于UDP沒有連接,所以服務器端不調用accept函數,客戶端不調用connect函數,而是服務器端直接調用recvfrom讀取客戶請求,sendto函數發送應答;客戶端調用sendto發送請求,調用recvfrom接收應答。可以看出,UDP服務器是迭代式服務器。
下面是sendto函數和recvfrom函數的定義,它們包含在<sys/socket.h>頭文件中:
ssize_t recvfrom(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr *from,socklen_t addrlen); ssize_t sendto(int sockfd,const void *buff,size_t nbytes,int flags,const struct sockaddr *to,socklen_t addrlen);前三個參數sockfd、buff和nbytes等同于read和write函數的三個參數:描述符、指向讀入或寫入的緩沖區的指針和讀寫字節數。flags參數這里設置為0;
sendto的to參數指向對端的協議地址,addrlen是一個值-結果參數,結果返回地址的大小;
recvfrom的后兩個參數類似于accept函數的最后兩個參數。
2、簡單的回射程序的UDP版本
下面是程序的代碼。
服務器端:
#include <stdio.h> #include <netinet/in.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> #define MAXLINE 1024 void dg_echo(int sockfd,struct sockaddr *pcliaddr,socklen_t clilen); int main(int argc,char *argv[]) {int sockfd;struct sockaddr_in servaddr,cliaddr;if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0){printf("socket error\n");return 0;}bzero(&servaddr,sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_addr.s_addr=htonl(INADDR_ANY);servaddr.sin_port=htons(5000);if(bind(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0){printf("bind error\n");return 0;}dg_echo(sockfd,(struct sockaddr*)&cliaddr,sizeof(cliaddr)); } void dg_echo(int sockfd,struct sockaddr *pcliaddr,socklen_t clilen) {int n;socklen_t len;char mesg[MAXLINE];for(;;){len=clilen;if((n=recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len))<0){printf("recvfrom error\n");return;}char buff[MAXLINE];if(sendto(sockfd,mesg,n,0,pcliaddr,len)<0){printf("sendto error\n");return;}} }下面是客戶端: #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #include <string.h> #define MAXLINE 1024 void dg_cli(FILE *fp,int sockfd,const struct sockaddr *pservaddr,socklen_t servlen); int main(int argc,char *argv[]) {int sockfd;struct sockaddr_in servaddr;if(argc!=2){printf("Usage:%s <IPaddress>\n",argv[0]);return 0;}bzero(&servaddr,sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_port=htons(5000);if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<0){printf("inet_pton error\n");return 0;}if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0){printf("socket error\n");return 0;}dg_cli(stdin,sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));return 0; } void dg_cli(FILE *fp,int sockfd,const struct sockaddr *pservaddr,socklen_t servlen) {int n;char sendline[MAXLINE],recvline[MAXLINE];while(fgets(sendline,MAXLINE,fp)!=NULL){if(sendto(sockfd,sendline,strlen(sendline),0,pservaddr,servlen)<0){printf("sendto error\n");return;}if((n=recvfrom(sockfd,recvline,MAXLINE,0,NULL,NULL))<0){printf("recvfrom error\n");return;}recvline[n]=0;fputs(recvline,stdout);} }下面是運行結果:打開服務器:
客戶端:
總結
以上是生活随笔為你收集整理的UNIX网络编程笔记(7):回射程序的UDP版本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 输卵管堵塞会不会影响生育
- 下一篇: 英雄联盟百宝箱皮肤7天后还能使用吗