Python socket上傳檔案的服務端和客戶端實現
socket官方文件:https://docs.python.org/2/library/socket.html
socket中文詳細介紹:http://blog.csdn.net/rebelqsp/article/details/22109925
檢視某埠是否被佔用(如6666埠):sudo netstat -nap | grep 6666 如果沒有查詢到6666埠則說明沒有被佔用(額,有點廢話了~~)
客戶端
建立 socket
連線到遠端伺服器
傳送資料
接收資料
關閉 socket
#!/usr/bin/env python # -*- coding=utf-8 -*- """ file: client.py socket client """ import socket import sys def socket_client(): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 6666)) except socket.error as msg: print msg sys.exit(1) print s.recv(1024) while 1: data = raw_input('please input work: ') s.send(data) print s.recv(1024) if data == 'exit': break s.close() if __name__ == '__main__': socket_client()
伺服器端
開啟 socket
繫結到特定的地址以及埠上
監聽連線
建立連線
接收/傳送資料
#!/usr/bin/env python
# -- coding=utf-8 --
""" file: service.py socket service """ import socket import threading import time import sys def socket_service(): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 防止socket server重啟後端口被佔用(socket.error: [Errno 98] Address already in use) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('127.0.0.1', 6666)) s.listen(10) except socket.error as msg: print msg sys.exit(1) print 'Waiting connection...' while 1: conn, addr = s.accept() t = threading.Thread(target=deal_data, args=(conn, addr)) t.start() def deal_data(conn, addr): print 'Accept new connection from {0}'.format(addr) conn.send('Hi, Welcome to the server!') while 1: data = conn.recv(1024) print '{0} client send data is {1}'.format(addr, data) #time.sleep(1) if data == 'exit' or not data: print '{0} connection close'.format(addr) conn.send('Connection closed!') break conn.send('Hello, {0}'.format(data)) conn.close() if __name__ == '__main__': socket_service()
copy以上兩個指令碼程式碼後,如果你想在本地測試,直接執行這兩個指令碼便是(注:先執行服務端service.py指令碼),下圖左邊是執行服務端指令碼,右邊開啟兩個終端與服務端socket進行通訊。
一屏開多個終端是不是很屌(強烈建議安裝此工具,非常方便好用)
終端增強工具Terminator
sudo apt-get install terminator # Ubuntu
yum -y install terminator # Centos
如果你想在兩臺不同機器上測試,把service.py指令碼上傳到伺服器(假設伺服器ip是:192.168.1.2),然後把client.py連線ip改為:192.168.1.2,service.py監聽的ip改為:192.168.1.2,接著執行這兩個指令碼即可
client.py
s.connect((‘192.168.1.2’, 6666))
service.py
s.bind((‘192.168.1.2’, 6666))
利用socket進行檔案、圖片等傳輸
傳輸檔案主要分以下兩步:
將要傳輸的檔案的基本資訊傳送到接收端(檔名、大小等其他資訊)
傳送端讀取檔案內容併發送過去,接受端將快取裡面的內容寫入檔案
注:以下發送檔案程式碼參考:http://www.mamicode.com/info-detail-1346172.html
傳送端程式碼
#!/usr/bin/env python
# -*- coding=utf-8 -*-
"""
file: send.py
socket client
"""
import socket
import os
import sys
import struct
def socket_client():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 6666))
except socket.error as msg:
print msg
sys.exit(1)
print s.recv(1024)
while 1:
filepath = raw_input('please input file path: ')
if os.path.isfile(filepath):
# 定義定義檔案資訊。128s表示檔名為128bytes長,l表示一個int或log檔案型別,在此為檔案大小
fileinfo_size = struct.calcsize('128sl')
# 定義檔案頭資訊,包含檔名和檔案大小
fhead = struct.pack('128sl', os.path.basename(filepath),
os.stat(filepath).st_size)
s.send(fhead)
print 'client filepath: {0}'.format(filepath)
fp = open(filepath, 'rb')
while 1:
data = fp.read(1024)
if not data:
print '{0} file send over...'.format(filepath)
break
s.send(data)
s.close()
break
if __name__ == '__main__':
socket_client()
接收端程式碼
#!/usr/bin/env python
# -*- coding=utf-8 -*-
"""
file: recv.py
socket service
"""
import socket
import threading
import time
import sys
import os
import struct
def socket_service():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 6666))
s.listen(10)
except socket.error as msg:
print msg
sys.exit(1)
print 'Waiting connection...'
while 1:
conn, addr = s.accept()
t = threading.Thread(target=deal_data, args=(conn, addr))
t.start()
def deal_data(conn, addr):
print 'Accept new connection from {0}'.format(addr)
#conn.settimeout(500)
conn.send('Hi, Welcome to the server!')
while 1:
fileinfo_size = struct.calcsize('128sl')
buf = conn.recv(fileinfo_size)
if buf:
filename, filesize = struct.unpack('128sl', buf)
fn = filename.strip('\00')
new_filename = os.path.join('./', 'new_' + fn)
print 'file new name is {0}, filesize if {1}'.format(new_filename,
filesize)
recvd_size = 0 # 定義已接收檔案的大小
fp = open(new_filename, 'wb')
print 'start receiving...'
while not recvd_size == filesize:
if filesize - recvd_size > 1024:
data = conn.recv(1024)
recvd_size += len(data)
else:
data = conn.recv(filesize - recvd_size)
recvd_size = filesize
fp.write(data)
fp.close()
print 'end receive...'
conn.close()
break
if __name__ == '__main__':
socket_service()
轉載:https://blog.csdn.net/luckytanggu/article/details/53491892