国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python cs架構(gòu)實現(xiàn)簡單文件傳輸

2020-01-04 14:48:52
字體:
供稿:網(wǎng)友

本文為大家分享了python cs架構(gòu)實現(xiàn)簡單文件的傳輸代碼,供大家參考,具體內(nèi)容如下

要實現(xiàn)簡單文件的傳輸我們必須考慮這些問題:

1.什么是c/s架構(gòu)?

顧名思義,就是客戶端端/服務器架構(gòu)。不同的人可能回答不一,但是有一點是相同的:服務器是一個軟件或硬件,用于向一個或多個客戶端提供所需要的服務,服務器存在的唯一目的就是等待客戶的請求,給這些客戶服務,然后等待其他的請求。

2.客戶端與服務端如何通信?

其實說白了就是互聯(lián)網(wǎng)中兩個主機該如何通信,首先我們用ip地址可以標示一臺主機,這樣就可以通信了么?當然也不行,我們還得標示主機中的進程,當然協(xié)議也是不可或缺的,是udp報文協(xié)議還是tcp數(shù)據(jù)流協(xié)議,這的看你個人的需求。用套介子來作為一個標示符,唯一標識網(wǎng)絡進程。

想明白這兩個問題我覺得這個問題有三分之一已經(jīng)解決了,接下來呢我選擇tcp協(xié)議來傳輸。

服務端:

        采用socket()函數(shù) 定義socket描述字

        bind()函數(shù)來把地址族中一個特定地址賦給socket,簡單來說就是把一個ipv4/ipv6地址+端口號組合賦給socket

        listen()函數(shù)把socket變成被動類型的,等待客戶連接請求。

        當客戶端發(fā)來消息時用accept()函數(shù)來接受請求,同時給服務端返回客戶端的socket描述字,接下來服務端以接收到的描述字來向客戶端發(fā)送信息以及接受信息。

        我們這個程序是實現(xiàn)文件傳輸,我的想法是類似于ftp程序接受客戶上傳下載文件的需求。服務端啟動后監(jiān)聽端口(我用的9500)等待客戶連接。客戶端三次握手建立連接后,客戶輸入命令來向客戶端發(fā)起請求,輸入‘ls'命令可以查看服務端可下載的文件,輸入‘put   文件名',‘get  文件名'可以上傳下載文件。上傳文件時客戶端打開本地文件以二進制方式讀取文件內(nèi)容并同時調(diào)用send()函數(shù)發(fā)送文件內(nèi)容,服務端以寫方式打開文件并將客戶端上傳內(nèi)容寫入文件,實現(xiàn)文件的上傳。下載文件與此類似,客戶端上傳送‘get  文件名'命令同時以寫方式打開文件 ,服務端收到命令以讀方式打開文件,并發(fā)送給服務端。

tcp三次握手建立連接:

python,cs架構(gòu),文件傳輸

當客戶端調(diào)用connect時,觸發(fā)了連接請求,向服務器發(fā)送了SYN J包,這時connect進入阻塞狀態(tài);服務器監(jiān)聽到連接請求,即收到SYN J包,調(diào)用accept函 數(shù)接收請求向客戶端發(fā)送SYN K ,ACK J+1,這時accept進入阻塞狀態(tài);客戶端收到服務器的SYN K ,ACK J+1之后,這時connect返回,并對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,連接建立。

tcp四次揮手斷開連接:

python,cs架構(gòu),文件傳輸

某個應用進程首先調(diào)用close主動關(guān)閉連接,這時TCP發(fā)送一個FIN M;另一端接收到FIN M之后,執(zhí)行被動關(guān)閉,對這個FIN進行確認。它的接收也作為文件結(jié)束符傳遞給應用進程,因為FIN的接收意味著應用進程在相應的連接上再也接收不到額外數(shù)據(jù);一段時間之后,接收到文件結(jié)束符的應用進程調(diào)用close關(guān)閉它的socket。這導致它的TCP也發(fā)送一個FIN N;接收到這個FIN的源發(fā)送端TCP對它進行確認。

服務端代碼:

#!/usr/bin/env pythonfrom socket import *import timeimport sysimport os HOST = 'localhost'PORT = 9500BUFIZ = 1024ADDR = (HOST,PORT) def recvfile(filename):  print 'starting receive file...'  f = open(filename,'wb')  cliSockfd.send('no problem')  while True:    data = cliSockfd.recv(4096)    if data == 'EOF':      print 'recved file success!'      break    f.write(data)  f.close() def sendfile(filename):  print 'starting send file...'  cliSockfd.send('no problem')  f = open(filename,'rb')  while True:    data = f.read(4096)    if not data:      break    cliSockfd.send(data)  f.close()  time.sleep(1)  cliSockfd.send('EOF')  print 'send file success!'def handle1(act,filename):  if act == 'put':    print 'recving msg!'    recvfile(filename)  elif act == 'get':    print 'sending msg!'    sendfile(filename)  else:    print 'error!' def handle2(act):  if act == 'ls':    path = sys.path[0]    every_file = os.listdir(path)    for filename in every_file:       cliSockfd.send(filename + ' ')    time.sleep(1)    cliSockfd.send('EOF')    print 'all filename has send to client success!'  else:    print 'command error' sockfd = socket(AF_INET,SOCK_STREAM)sockfd.bind(ADDR)sockfd.listen(5)while True:  print 'waiting for connection...'  cliSockfd,addr = sockfd.accept()  print '...connected from:',addr    while True:    msg = cliSockfd.recv(4096)    if msg == 'close':      print 'client closed'      break    info = msg.split()    if len(info) == 2:      handle1(*info)    elif len(info) == 1:      handle2(*info)    else:      print 'command error!'      break

客戶端代碼:

#!/usr/bin/env pythonimport sysimport socketimport timeHOST = 'localhost'PORT = 9500BUFSIZ = 1024ADDR = (HOST,PORT) cliSockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM) def recvfile(filename):  f = open(filename,'wb')  while True:    msg = cliSockfd.recv(4096)    if msg == 'EOF':      print 'recv file success!'      break    f.write(msg)  f.closedef sendfile(filename):  f = open(filename,'rb')  while True:    msg = f.read(4096)    if not msg:       break    cliSockfd.sendall(msg)  f.close()  time.sleep(1)  cliSockfd.sendall('EOF')  print 'send file success'def confirm(cliSockfd,client_command):  cliSockfd.send(client_command)  msg = cliSockfd.recv(4096)  if msg == 'no problem':    return True def handle1(act,filename):  if act == 'put':    if confirm(cliSockfd,client_command):      sendfile(filename)    else:      print 'server error1!'  elif act == 'get':    if confirm(cliSockfd,client_command):      recvfile(filename)    else:      print 'server error2!'  else:    print 'command error!'def handle2(act):  if act == 'ls':    cliSockfd.send('ls')    while True:      msg = cliSockfd.recv(1024)      if msg == 'EOF':        break      print msg  else:    print 'command error' try:  cliSockfd.connect(ADDR)  print 'connect to ',ADDR  while True:    client_command = raw_input('>>>')    if not client_command:      continue    msg = client_command.split()    if len(msg) == 2:      handle1(*msg)    elif len(msg) == 1 and msg != ['close']:      handle2(*msg)    elif len(msg) == 1 and msg == ['close']:      cliSockfd.send('close')      break    else:      print 'command error'except socket.error,e:  print 'error:',efinally:  cliSockfd.close()

運行截圖:

服務端:

python,cs架構(gòu),文件傳輸

客戶端:

python,cs架構(gòu),文件傳輸

歡迎各位大牛,多提寶貴意見。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到python教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 文登市| 潜江市| 南部县| 乳源| 临泉县| 潞西市| 青海省| 石台县| 苗栗县| 田阳县| 浮山县| 武鸣县| 田林县| 尉氏县| 禹城市| 华容县| 扶绥县| 沿河| 伊金霍洛旗| 历史| 芒康县| 巧家县| 广德县| 田林县| 昂仁县| 吉木乃县| 渭源县| 砀山县| 芦山县| 永春县| 武隆县| 兴山县| 晋中市| 宜丰县| 朝阳市| 友谊县| 吉木萨尔县| 龙江县| 开远市| 尤溪县| 永昌县|