基於UDP的服務端 客戶端

2021-10-02 10:18:55 字數 3203 閱讀 2595

udp套接字的特點

udp提供的是不可靠的傳輸服務。如果只考慮可靠性tcp要優於udp,但是udp的結構要比tcp更簡潔。udp不會傳送ack的應答資訊,也不會像seq那樣給資料分配序號。因此,udp效能有時比tcp高出很多。程式設計實現簡單。可靠性雖然不及tcp,但也不會像想象中那麼頻繁的資料損毀。

udp的高效使用

如果收發資料量小但需要頻繁連線時,udp比tcp更高效。

udp中服務端和客戶端沒有連線

udp伺服器端和客戶端不像tcp那樣在連線狀態下交換資料,因此與tcp不同無需經過連線過程。不必呼叫tcp連線過程中呼叫listen和accept函式。udp中只有建立套接字過程和交換資料過程。

udp服務端和客戶端均只需乙個套接字

tcp中,套接字應該是一對一的關係。在udp中不管是服務端還是客戶端都只需乙個套接字。就可以向任意主機傳輸資料。

基於udp的資料i/o函式

建立好tcp套接字後,傳輸資料時無需再新增位址資訊。因為tcp套接字將保持與對方套接字的連線。既tcp套接字知道目標位址資訊。但udp套接字不會保持連線狀態,因此每次傳輸資料都要新增目標位址資訊。

# include ssize_t sendto(int sock,void* buf,size_t nbytes,int flags,struct sockaddr *to,socklen_t addrlen_t);

成功時返回傳輸位元組數,失敗時返回-1

sock:用於傳輸資料的udp套接字檔案描述符

buf: 儲存待傳輸資料的緩衝位址值

nbytes:待傳輸資料的資料長度,以位元組為單位

flags:可選項引數,若沒有則傳遞0

to:存有目標位址資訊的sockaddr結構體變數位址值

addrlen:傳遞給引數to的位址值結構體變數長度

udp資料的傳送端並不固定,因此該函式定以可接收傳送端資訊的形式,也就是將同時返回udp資料報中的傳送端資訊。

# include ssize_t recvfrom(int sock,void* buff,size_t nbytes,int flags,struct sockaddr* from,socklen_t* addrlen);

成功時返回接收位元組數,失敗返回-1

sock:用於傳輸資料的udp套接字檔案描述符

buf: 儲存待傳輸資料的緩衝位址值

nbytes:待傳輸資料的資料長度,以位元組為單位

flags:可選項引數,若沒有則傳遞0

from:存有傳送端位址資訊的sockaddr結構體變數位址值

addrlen:傳遞給引數from的位址值結構體變數長度位址值

基於udp的回聲服務端/客戶端

# include # include # include # include # include # include # define buf_size 1024

void error_handling(char * message);

int main(int argc,char** ar**)

sock_svr=socket(pf_inet,sock_dgram,0);

if(sock_svr==-1)

memset(&svr_addr,0,sizeof(svr_addr));

svr_addr.sin_family=af_inet;

svr_addr.sin_addr.s_addr=htonl(inaddr_any);

svr_addr.sin_port=htons(atoi(ar**[1]));

if(bind(sock_svr,(struct sockaddr*)&svr_addr,sizeof(svr_addr))==-1)

error_handling("bind () error");

while(1)

/*udp具有資料邊界,傳輸中i/o函式呼叫次數要完全一致

*//*for(int i=0;i<3;++i)

*/close(sock_svr);

return 0;

}void error_handling(char * message)

# include # include # include # include # include # include # define buf_size 1024

void error_handling(char * message);

int main(int argc,char** ar**)

sock_clnt=socket(pf_inet,sock_dgram,0);

if(sock_clnt==-1)

error_handling("socket() error");

memset(&to_addr,0,sizeof(to_addr));

to_addr.sin_family=af_inet;

to_addr.sin_addr.s_addr=inet_addr(ar**[1]);

to_addr.sin_port=htons(atoi(ar**[2]));

connect(sock_clnt,(struct sockaddr*)&to_addr,sizeof(to_addr));//建立已連線udp套接字

/*針對udp套接字呼叫connect函式並不意味著要與對方udp套接字連線,只是向udp套接字註冊ip和埠號

*/while(1)

/*驗證udp具有資料邊界

*//*char msg1="hello";

char msg2="world";

char msg3="nice to meet you";

sendto(sock_clnt,msg1,strlen(msg1)+1,0,(struct sockaddr*)&to_addr,sizeof(to_addr));

sendto(sock_clnt,msg2,strlen(msg2)+1,0,(struct sockaddr*)&to_addr,sizeof(to_addr));

sendto(sock_clnt,msg3,strlen(msg3)+1,0,(struct sockaddr*)&to_addr,sizeof(to_addr));

*/close(sock_clnt);

return 0;

}void error_handling(char * message)

udp服務端 客戶端

個數 2的16次方 埠是資料發出或接收的入口 埠的目的 通過埠號找到對應的程序,完成資料的通訊 著名埠0 1023 這是建立了乙個基於udp協議的服務端 import socket todo 1.0 建立了乙個套接字,用來連線客戶端,傳送與接收資料 udp server socket.socket ...

TCP以及UDP服務端和客戶端

tcp server.py from datetime import datetime import socket address localhost 6789 max size 1000 print starting the server at datetime.now print waiting...

Python UDP客戶端 服務端

udpclient.py coding utf 8 from socket import servername 127.0.0.1 伺服器位址,本例中使用一台遠端主機 serverport 12000 伺服器指定的埠 clientsocket socket af inet,sock dgram 建立...