udp網路程式採用的通訊模型與tcp網路程式模型有很大的不同,具體見圖7-4所示。
udp伺服器首先進行初始化操作:呼叫函式socket建立乙個資料報型別的套接字,函式bind將這個套接字與伺服器的公認位址繫結在一起。然後呼叫函式recvfrom接收udp客戶機的資料報。udp客戶機首先呼叫函式socket建立乙個資料報套接字,然後呼叫函式sendto向伺服器傳送資料報。在結束通訊後,客戶機呼叫close關閉udp套接字,伺服器繼續使用這個udp套接字接收其它客戶機的資料報。
下面我們就學習一下圖7-4中的一些函式用法。socket函式的用法在上節已經介紹了,這裡就不在敘述。
資料傳送函式sendto的原型為:
#include
#include
int sendto(int sockfd,const void *msg,int len,unsigned int flags,const struct sockaddr *to,int tolen);
資料接收函式recvfrom的原型為:
#include
#include
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
引數from儲存源機的ip位址和埠號;fromlen為此位址的長度。當recvfrom()返回時,fromlen包含實際存入from中的資料位元組數,出現錯誤時返回-1。
下面我們就具體編寫乙個簡單的基於udp協議的伺服器/客戶端程式
伺服器端程式server.c
/*************本程式用於建立服務端程式*****************/
#include
#include
#include
#include
#include
#define myport 8866 /*定義埠為8866*/
#define max_msg_size 1024
int main(void)
/* 伺服器端填充 sockaddr_in結構 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=af_inet;
server_addr.sin_addr.s_addr=htonl(inaddr_any);
server_addr.sin_port=htons(myport);
/*繫結套接字*/
if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))
addrlen=sizeof(struct sockaddr);
printf(「the server is waiting datas:\n」);
/* 接收客戶端資料報,返回的為接收到的位元組數 */
n=recvfrom(sockfd,buffer,max_msg_size,0,
(struct sockaddr *)&client_addr,&addrlen);
buffer[n]='\0';
printf("got packer form %s\npacket contains:%s\n",
inet_ntoa(client_addr.sin_addr),buffer);
close(sockfd);
}客戶端程式client.c
#include
#include
#include
#include
#include
#include
#include
#include
#define max_buf_size 1024
#define myport 8866 /*定義埠為8866*/
int main(int argc,char *argv)
/*gethostbyname可通過名稱得到主機的ip位址*/
host=gethostbyname(argv[1]);
/*建立套接字*/
sockfd=socket(af_inet,sock_dgram,0);
if(sockfd
/* 填充服務端的資料 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=af_inet;
server_addr.sin_port=htons(myport);
server_addr.sin_addr=*((struct in_addr *)host->h_addr);
printf("please input some characters:\n");
scanf("%s",buffer);
/*向伺服器端傳送資料報*/
n=sendto(sockfd,buffer,strlen(buffer),0,
(struct sockaddr *)&server_addr,sizeof(struct sockaddr));
printf("sent %d bytes to %s\n",n,inet_ntoa(server_addr.sin_addr));
close(sockfd);
return 0;
}makefile檔案的編寫
all:server client
server:server.c
gcc –o server server.c
client:client.c
gcc –o client client.c
clean:
rm –f server
rm –f client
編譯執行:
執行make後會產生兩個程式server(伺服器端)和client(客戶端)。先執行./server,這時螢幕顯示「the server is waiting datas:」,然後進入等待狀態。螢幕顯示如下:
./server
the server is waiting datas:
然後在本機開啟另外乙個終端,執行./client localhost,表明此客戶端是相位於本機的伺服器傳送資料報,這時螢幕顯示如下:
./client localhost
please input some characters:
abcdefghijk
sent 11 bytes to 127.0.0.1
這時,執行伺服器程式的終端會顯示:
got packer form 127.0.0.1 packet contains: abcdefghijk
UDP 客戶端伺服器
udp 客戶端 include include include include include define size 100 define ip 127.0.0.1 define port 10086 int main struct sockaddr in addr 建立socket udp so...
基於UDP的伺服器端和客戶端
前面的文章中我們給出了幾個tcp的例子,對於udp而言,只要能理解前面的內容,實現並非難事。udp不像tcp,無需在連線狀態下交換資料,因此基於udp的伺服器端和客戶端也無需經過連線過程。也就是說,不必呼叫 listen 和 accept 函式。udp中只有建立套接字的過程和資料交換的過程。tcp中...
6 1 基於UDP的伺服器端 客戶端
1.udp套接字原理 可靠性方面來說,tcp的確比udp好,但是udp的結構比tcp簡潔,不會傳送類似ack應答訊息,也不會有seq序號,效能有時比tcp高出很多。同時區分tcp和udp的重要標誌是流控制 tcp的生命在於流控制。圖中,ip的作用是讓離開主機b的udp資料報準確傳送到主機 但是最終交...