日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++ udp多线程 例子_[内附完整源码和文档] 基于udp实现tcp功能进行大文件传输

發(fā)布時(shí)間:2025/3/11 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ udp多线程 例子_[内附完整源码和文档] 基于udp实现tcp功能进行大文件传输 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.項(xiàng)目要求
Please choose one of following programing languages: C, C++, Java, Python;
本項(xiàng)目采用的是python3.6
LFTP should use a client-server service model;
本項(xiàng)目使用客戶端-服務(wù)器的模式
LFTP must include a client side program and a server side program; Client side program can not only send a large file to the server but also download a file from the server.
Sending file should use the following format:
LFTP lsend myserver mylargefile
Getting file should use the following format
LFTP lget myserver mylargefile
The parameter myserver can be a url address or an IP address.
本項(xiàng)目,客戶端不僅可以向服務(wù)器上傳大文件,也可以從服務(wù)器下載大文件
LFTP should use UDP as the transport layer protocol.
本項(xiàng)目利用UDP來(lái)作為傳輸層協(xié)議
LFTP must realize 100% reliability as TCP;
本項(xiàng)目實(shí)現(xiàn)類似TCP的100%可靠性,處理了丟包,超時(shí),數(shù)據(jù)包順序不一致等問(wèn)題
LFTP must implement flow control function similar as TCP;
本項(xiàng)目實(shí)現(xiàn)了類似TCP的流控制,在接收方維護(hù)一個(gè)rwnd接收窗口
LFTP must implement congestion control function similar as TCP;
本項(xiàng)目實(shí)現(xiàn)了類似TCP的阻塞控制,在發(fā)送方維護(hù)一個(gè)cwnd阻塞窗口
LFTP server side must be able to support multiple clients at the same time;
本項(xiàng)目支持多個(gè)用戶同時(shí)向服務(wù)器收發(fā)文件,使用了多線程的機(jī)制
LFTP should provide meaningful debug information when programs are
executed.
本項(xiàng)目提供了有意義的debug消息來(lái)顯示發(fā)送情況,包括丟包,阻塞等事件的處理
二. 設(shè)計(jì)思路
基于UDP的傳輸過(guò)程如下圖所示:


基于UDP來(lái)實(shí)現(xiàn)類似TCP的大文件傳輸,代碼構(gòu)建過(guò)程:

利用socket實(shí)現(xiàn)簡(jiǎn)單字符串傳送

對(duì)于文件進(jìn)行處理,將1的代碼改造成文件的傳送

對(duì)于文件進(jìn)行分段,打包發(fā)送

發(fā)送過(guò)程使用多線程

服務(wù)器與客戶端連接的建立與斷開(kāi),三方握手,四次揮手

處理命令行輸入命令,與服務(wù)器進(jìn)行交互

添加ACK反饋包,建立判斷重復(fù)ACK機(jī)制

丟包事件的判斷與處理

接收方的序列號(hào)是否正確,要求重發(fā)

接收方的流控制,構(gòu)建接收窗口

發(fā)送方的阻塞控制

三. 模塊設(shè)計(jì)
3.1 設(shè)置傳送數(shù)據(jù)包的數(shù)據(jù)結(jié)構(gòu),以及反饋包的數(shù)據(jù)結(jié)構(gòu)
這里的數(shù)據(jù)包與反饋包結(jié)構(gòu)我采用的是struct結(jié)構(gòu)體,其中一個(gè)數(shù)據(jù)包所帶有文件數(shù)據(jù)為1024bytes,而頭文件包括序列號(hào),確認(rèn)號(hào),文件結(jié)束標(biāo)志,為24bytes。

反饋包包括ack確認(rèn),rwnd接收窗口的大小。

傳送一個(gè)包的結(jié)構(gòu),包含序列號(hào),確認(rèn)號(hào),文件結(jié)束標(biāo)志,數(shù)據(jù)包

packet_struct = struct.Struct(‘III1024s’)

接收后返回的信息結(jié)構(gòu),包括ACK確認(rèn),rwnd

feedback_struct = struct.Struct(‘II’)
BUF_SIZE = 1024+24
FILE_SIZE = 1024
3.2 服務(wù)器部分:處理客戶端傳輸?shù)拿?#xff0c;并使用多線程來(lái)處理
服務(wù)器先建立一個(gè)主的線程來(lái)監(jiān)聽(tīng)接收客戶端到來(lái)的命令,將命令接收后傳送到server_thread來(lái)處理,傳遞的參數(shù)包括客戶端的命令參數(shù)以及客戶端的地址。

···
IP = ‘192.168.88.129’
SERVER_PORT = 7777
···
def main():
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 綁定端口:
s.bind((IP, SERVER_PORT))
while True:
data,client_addr = s.recvfrom(BUF_SIZE)
# 多線程處理
my_thread = threading.Thread(target=server_thread,args=(client_addr,data))
my_thread.start()
3.3 服務(wù)器部分:多線程處理函數(shù)
該函數(shù)要為每一個(gè)客戶端新建一個(gè)socket,并將命令解析得到客戶端所需要的操作

def server_thread(client_addr,string):
# 處理傳輸過(guò)來(lái)的str,得到文件名,命令
order = ‘’
try:
order = string.decode(‘utf-8’).split(’,’)[0]
file_name = string.decode(‘utf-8’).split(’,’)[1]
except Exception as e:
return
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
···
除此以外,還需要像TCP建立連接一樣來(lái)進(jìn)行三方握手,確認(rèn)連接才開(kāi)始發(fā)送。

客戶端先申請(qǐng)連接

三方握手

發(fā)送請(qǐng)求建立連接

s.sendto(data,server_addr)

接收連接允許

print(data.decode(‘utf-8’))
data,server_addr = s.recvfrom(BUF_SIZE)
print(‘來(lái)自服務(wù)器’, server_addr, '的數(shù)據(jù)是: ', data.decode(‘utf-8’))
服務(wù)器確認(rèn)連接

文件存在,返回確認(rèn)信號(hào)

s.sendto(‘連接就緒’.encode(‘utf-8’),client_addr)
data,client_addr = s.recvfrom(BUF_SIZE)
print(‘來(lái)自’,client_addr,‘的數(shù)據(jù)是:’,data.decode(‘utf-8’))
客戶端再發(fā)送確認(rèn)包,這時(shí)連接就建立完畢

第三次握手,確認(rèn)后就開(kāi)始接收

data=‘ACK’.encode(‘utf-8’)
s.sendto(data,server_addr)
下面是四次揮手的過(guò)程:

當(dāng)服務(wù)器執(zhí)行完客戶端的命令后,要像tcp一樣來(lái)執(zhí)行斷開(kāi)連接操作,斷開(kāi)連接后可以把socket釋放掉,即調(diào)用close函數(shù)。

服務(wù)器:

print(’n開(kāi)始中斷連接’)

中斷連接,四次揮手

data,server_addr = s.recvfrom(BUF_SIZE)
print(data.decode(‘utf-8’))
data = ‘Server allows disconnection’
s.sendto(data.encode(‘utf-8’),client_addr)
print(data)
data = ‘Server requests disconnection’
s.sendto(data.encode(‘utf-8’),client_addr)
print(data)
data,server_addr = s.recvfrom(BUF_SIZE)
print(data.decode(‘utf-8’))
print(‘The connection between client and server has been interrupted’)
s.close()
客戶端:

中斷連接,四次揮手

data = ‘Client requests disconnection’
print(data)
s.sendto(data.encode(‘utf-8’),server_addr)
data,client_addr = s.recvfrom(BUF_SIZE)
print(data.decode(‘utf-8’))
data,client_addr = s.recvfrom(BUF_SIZE)
print(data.decode(‘utf-8’))
data = ‘Client allows disconnection’
s.sendto(data.encode(‘utf-8’),server_addr)
print(data)
print(‘The connection between client and server has been interrupted’)
s.close()
說(shuō)完建立連接與斷開(kāi)連接,回到多線程處理函數(shù),對(duì)于lsend,lget函數(shù)的判斷:當(dāng)命令是lget時(shí),要判斷服務(wù)器是否存在該文件,如果不存在則直接返回信息后,關(guān)閉socket;若存在該文件直接進(jìn)入lget函數(shù)來(lái)進(jìn)行處理。當(dāng)命令是lsend時(shí),直接進(jìn)入lsend函數(shù)來(lái)進(jìn)行處理。

if order == ‘lget’:
# 處理文件不存在的情況
if os.path.exists(file_name) is False:
data = ‘FileNotFound’.encode(‘utf-8’)
s.sendto(data, client_addr)
# 關(guān)閉socket
s.close()
return
# 文件存在,返回確認(rèn)信號(hào)
s.sendto(‘連接就緒’.encode(‘utf-8’),client_addr)
data,client_addr = s.recvfrom(BUF_SIZE)
print(‘來(lái)自’,client_addr,‘的數(shù)據(jù)是:’,data.decode(‘utf-8’))
lget(s,client_addr,file_name)
elif order == ‘lsend’:
s.sendto(‘是否可以連接’.encode(‘utf-8’),client_addr)
# 等待確認(rèn)
data,client_addr = s.recvfrom(BUF_SIZE)
print(‘來(lái)自’,client_addr,‘的數(shù)據(jù)是:’,data.decode(‘utf-8’))
lsend(s,client_addr,file_name)

完整的源碼和詳細(xì)的文檔,上傳到了 WRITE-BUG技術(shù)共享平臺(tái) 上,需要的請(qǐng)自取:

https://www.write-bug.com/article/2998.html

總結(jié)

以上是生活随笔為你收集整理的c++ udp多线程 例子_[内附完整源码和文档] 基于udp实现tcp功能进行大文件传输的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。