socket實現UDP網路通訊程式

2021-10-03 19:12:15 字數 4198 閱讀 2171

首先回顧socket套接字程式設計

socket就是一套網路程式設計介面:上層使用者通過這些介面簡單地完成網路通訊傳輸不需要關心內部實現【類似中介軟體】

五元組:(源ip位址,源埠,目的ip位址,目的埠,協議),用於標識資料,每個網路中資料都會包含

套接字程式設計:使用socket介面實現通訊

網路通訊:

網路中兩端主機上程序間通訊,兩端分別是客戶端、伺服器端

客戶端:永遠主動傳送請求,傳送前必須知道伺服器端位址

伺服器端:永遠被動接收請求,告訴客戶端自己的位址【通常是不變的】

注意:服務端socket只繫結伺服器端主機上的ip位址,客戶端也是只繫結自己主機上的ip

udp網路通訊

udp【使用者資料報協議】:無連線、不可靠、無序、有最大長度限制

由於udp特性:作業系統接收到資料後判斷目的位址資訊,然後去核心中socket容器查詢,找到就直接放在接收緩衝區,如果沒找到會丟棄掉該資料

客戶端流程

建立套接字——核心中建立socket結構體,向程序返回操作控制代碼。通過核心中socket結構體與網絡卡建立聯絡

繫結位址資訊——為核心中建立的socket結構體新增位址描述資訊(ip位址、埠)

傳送資料——把資料先拷貝到核心中socket結構體的傳送緩衝區,os在需要時取出資料並對其進行封裝,通過網絡卡傳送出去

接收資料——從socket結構體的接收緩衝區取出資料,根據源ip、目的ip確認對端

關閉套接字,釋放資源

伺服器流程

建立套接字

繫結位址資訊

接收資料

傳送資料

關閉套接字,釋放資源 實現

客戶端:

#include

#include

#include

#include

//close介面

#include

//atoi介面

#include

//位址結構定義

#include

//位元組序轉換介面

#include

//套接字介面

class

udpsocket

//建立套接字

bool

socket()

return

true;}

//繫結位址資訊

bool

bind

(const std::string &ip,

uint32_t port)

return

true;}

bool

send

(const std::string &data,

const std::string &ip,

uint16_t port)

return

true;}

//接收資料

bool

recv

(std::string *buf,std::string *ip=

null

,uint16_t

*port=

null);

//緩衝區

ret=

recvfrom

(_sockfd,tmp,

4096,0

,(struct sockaddr*

)&addr,

&len);if

(ret<0)

buf-

>

assign

(tmp,ret)

;//為buf申請ret大小空間,從tmp中拷貝ret長資料

//使用者不獲取就不轉換

if(ip!=

null

)*ip=

inet_ntoa

(addr.sin_addr);if

(port!=

null

)*port=

ntohs

(addr.sin_port)

;return

true;}

//關閉套接字

void

close()

private

://套接字描述符

int _sockfd;};

#define check_ret(q) if((q)==false)

intmain

(int argc,

char

* ar**)

std::string ip_addr=ar**[1]

;//服務端位址

uint16_t port_addr=

atoi

(ar**[2]

);udpsocket sock;

check_ret

(sock.

socket()

);while(1

) sock.

close()

;return0;

}

伺服器端:

#include

#include

#include

#include

#include

//sockaddr結構體/ ipproto_udp

#include

//包含一些位元組序轉換的介面

#include

//套接字介面標頭檔案

intmain

(int argc,

char

*ar**)

const

char

*ip_addr = ar**[1]

;uint16_t port_addr =

atoi

(ar**[2]

);int sockfd=

socket

(af_inet,sock_dgram,ipproto_udp);if

(sockfd<0)

struct sockaddr_in addr;

addr.sin_family=af_inet;

addr.sin_port=

htons

(port_addr)

; addr.sin_addr.s_addr=

inet_addr

(ip_addr)

; socklen_t len=

sizeof

(struct sockaddr_in)

;int ret=

bind

(sockfd,

(struct sockaddr*

)&addr,len);if

(ret<0)

while(1

);struct sockaddr_in cliaddr;

socklen_t len =

sizeof

(struct sockaddr_in)

;//阻塞接收資料,放入buf,傳送端位址放在cliaddr

int ret=

recvfrom

(sockfd,buf,

1023,0

,(struct sockaddr*

)&cliaddr,

&len);if

(ret<0)

printf

("client say> %s\n"

,buf)

;printf

("server say>");

fflush

(stdout);

memset

(buf,

0x00

,1024);

scanf

("%s"

,buf)

;//將buf中資料傳送到客戶端

ret=

sendto

(sockfd,buf,

strlen

(buf),0

,(struct sockaddr*

)&cliaddr,len);if

(ret<0)

}close

(sockfd)

;}

執行後,當在客戶端輸入時伺服器端就能收到客戶端傳送的資訊:

這時伺服器端介面顯示:

網路通訊UDP

udp 前面已經講過tcp網路通訊,然後tcp每次通訊都要進行三次握手連線,雖然傳輸的可靠性比較高,但對於一些及時性的資料的傳輸顯得太過費時,所以就有了udp這種無連線通訊,但資料容易出錯。那些函式我這裡就不講了,直接看我上乙個部落格就行,我這裡直接附例子了。udpserver.c include ...

udp網路通訊

建立套接字 傳送 接收 資料 關閉套接字 伺服器需要通過bind固定本機ip和port import socket 1.建立udp套接字 udp socket socket.socket socket.af inet,socket.sock dgram 2.傳送資料 send socket.send...

udp網路通訊

如何使用udp實現通訊 編碼 encode 解碼 decode傳送 sendto udp傳送資訊功能 連線模組,導包 import socket 建立udp套接字 udp socket socket.socket socket.af inet,socket.sock dgram 死迴圈 while ...