Trong chương này, chúng ta sẽ mở rộng Lập trình mạng Python I - Máy chủ / Máy khách cơ bản A và cố gắng truyền tệp từ một máy chủ đến nhiều máy khách. Mục đích chính là để kiểm tra hiệu suất của máy chủ mà máy khách tải xuống tệp từ đó
Đây là mã để gửi tệp từ máy chủ cục bộ đến máy khách cục bộ
# server.py import socket # Import socket module port = 60000 # Reserve a port for your service. s = socket.socket[] # Create a socket object host = socket.gethostname[] # Get local machine name s.bind[[host, port]] # Bind to the port s.listen[5] # Now wait for client connection. print 'Server listening....' while True: conn, addr = s.accept[] # Establish connection with client. print 'Got connection from', addr data = conn.recv[1024] print['Server received', repr[data]] filename='mytext.txt' f = open[filename,'rb'] l = f.read[1024] while [l]: conn.send[l] print['Sent ',repr[l]] l = f.read[1024] f.close[] print['Done sending'] conn.send['Thank you for connecting'] conn.close[] # client.py import socket # Import socket module s = socket.socket[] # Create a socket object host = socket.gethostname[] # Get local machine name port = 60000 # Reserve a port for your service. s.connect[[host, port]] s.send["Hello server!"] with open['received_file', 'wb'] as f: print 'file opened' while True: print['receiving data...'] data = s.recv[1024] print['data=%s', [data]] if not data: break # write data to a file f.write[data] f.close[] print['Successfully get the file'] s.close[] print['connection closed']
Đầu ra trên máy chủ cục bộ
Server listening.... Got connection from ['192.168.56.10', 62854] ['Server received', "'Hello server!'"] ['Sent ', "'1 1234567890\\n ... ['Sent ', "'4567890\\n105 ... ['Sent ', "'300 1234567890\\n'"] Done sending
Đầu ra trên một máy khách cục bộ
file opened receiving data... data=1 1234567890 2 1234567890 ... 103 1234567890 104 123 receiving data... data=4567890 105 1234567890 106 1234567890 ... 299 1234567890 receiving data... data=300 1234567890 Thank you for connecting receiving data... data= Successfully get the file connection closed
chuyển tập tin tcp đa luồng trên localhost
Mã máy chủ của chúng tôi ở trên chỉ có thể tương tác với một khách hàng. Tuy nhiên, nếu chúng tôi cố gắng kết nối với ứng dụng khách thứ hai, đơn giản là nó sẽ không trả lời ứng dụng khách mới. Để server tương tác với nhiều client ta cần sử dụng multi-threading. Đây là tập lệnh máy chủ mới để chấp nhận nhiều kết nối máy khách
# server2.py import socket from threading import Thread from SocketServer import ThreadingMixIn TCP_IP = 'localhost' TCP_PORT = 9001 BUFFER_SIZE = 1024 class ClientThread[Thread]: def __init__[self,ip,port,sock]: Thread.__init__[self] self.ip = ip self.port = port self.sock = sock print " New thread started for "+ip+":"+str[port] def run[self]: filename='mytext.txt' f = open[filename,'rb'] while True: l = f.read[BUFFER_SIZE] while [l]: self.sock.send[l] #print['Sent ',repr[l]] l = f.read[BUFFER_SIZE] if not l: f.close[] self.sock.close[] break tcpsock = socket.socket[socket.AF_INET, socket.SOCK_STREAM] tcpsock.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1] tcpsock.bind[[TCP_IP, TCP_PORT]] threads = [] while True: tcpsock.listen[5] print "Waiting for incoming connections..." [conn, [ip,port]] = tcpsock.accept[] print 'Got connection from ', [ip,port] newthread = ClientThread[ip,port,conn] newthread.start[] threads.append[newthread] for t in threads: t.join[] # client2.py #!/usr/bin/env python import socket TCP_IP = 'localhost' TCP_PORT = 9001 BUFFER_SIZE = 1024 s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.connect[[TCP_IP, TCP_PORT]] with open['received_file', 'wb'] as f: print 'file opened' while True: #print['receiving data...'] data = s.recv[BUFFER_SIZE] print['data=%s', [data]] if not data: f.close[] print 'file close[]' break # write data to a file f.write[data] print['Successfully get the file'] s.close[] print['connection closed']
Dưới đây là đầu ra từ bảng điều khiển máy chủ khi chúng tôi chạy đồng thời hai máy khách
$ python server2.py Waiting for incoming connections... Got connection from ['127.0.0.1', 55184] New thread started for 127.0.0.1:55184 Waiting for incoming connections... Got connection from ['127.0.0.1', 55185] New thread started for 127.0.0.1:55185 Waiting for incoming connections...
tải xuống tệp tcp từ EC2 về cục bộ
Trong các mã sau, chúng tôi đã thực hiện hai thay đổi
- ip đã chuyển sang amazon ec2 ip
- Để tính thời gian tải 1 file ta nhập module time
# server3.py on EC2 instance import socket from threading import Thread from SocketServer import ThreadingMixIn # TCP_IP = 'localhost' TCP_IP = socket.gethostbyaddr["your-ec2-public_ip"][0] TCP_PORT = 60001 BUFFER_SIZE = 1024 print 'TCP_IP=',TCP_IP print 'TCP_PORT=',TCP_PORT class ClientThread[Thread]: def __init__[self,ip,port,sock]: Thread.__init__[self] self.ip = ip self.port = port self.sock = sock print " New thread started for "+ip+":"+str[port] def run[self]: filename='mytext.txt' f = open[filename,'rb'] while True: l = f.read[BUFFER_SIZE] while [l]: self.sock.send[l] #print['Sent ',repr[l]] l = f.read[BUFFER_SIZE] if not l: f.close[] self.sock.close[] break tcpsock = socket.socket[socket.AF_INET, socket.SOCK_STREAM] tcpsock.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1] tcpsock.bind[[TCP_IP, TCP_PORT]] threads = [] while True: tcpsock.listen[5] print "Waiting for incoming connections..." [conn, [ip,port]] = tcpsock.accept[] print 'Got connection from ', [ip,port] newthread = ClientThread[ip,port,conn] newthread.start[] threads.append[newthread] for t in threads: t.join[] # client3.py on local machine #!/usr/bin/env python #!/usr/bin/env python import socket import time #TCP_IP = 'localhost' TCP_IP = 'ip-ec2-instance' TCP_PORT = 60001 BUFFER_SIZE = 1024 s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.connect[[TCP_IP, TCP_PORT]] clock_start = time.clock[] time_start = time.time[] with open['received_file', 'wb'] as f: print 'file opened' while True: #print['receiving data...'] data = s.recv[1024] #print['data=%s', [data]] if not data: f.close[] print 'file close[]' break # write data to a file f.write[data] print['Successfully get the file'] s.close[] print['connection closed'] clock_end = time.clock[] time_end = time.time[] duration_clock = clock_end - clock_start print 'clock: start = ',clock_start, ' end = ',clock_end print 'clock: duration_clock = ', duration_clock duration_time = time_end - time_start print 'time: start = ',time_start, ' end = ',time_end print 'time: duration_time = ', duration_time
Bảng điều khiển máy chủ hiển thị đầu ra sau khi kết nối từ máy tại nhà cục bộ của tôi
$ python server3.py TCP_IP= ec2-... TCP_PORT= 60001 Waiting for incoming connections... Got connection from ['108.239.135.40', 56742] New thread started for 108.239.135.40:56742
IP là của isp
Trên máy Mac cục bộ của tôi
$ python client3.py file opened file close[] Successfully get the file connection closed clock: start = 0.018806 end = 0.038608 clock: duration_clock = 0.019802 time: start = 1434991840.37 end = 1434991840.42 time: duration_time = 0.0457620620728
Tệp được tải xuống từ EC2, got_file rất đơn giản và có dạng như thế này
________số 8Thời gian tải xuống so với số lượng khách hàng
Đây là đầu ra hiển thị thời gian của đồng hồ treo tường tùy thuộc vào số lượng kết nối đồng thời
Máy chủ của chúng tôi được đặt tại California và hình ảnh sau đây so sánh tốc độ tải xuống giữa Hoa Kỳ và Nhật Bản