本例实现的功能:不管服务器从客户端收到什么输入,都会将其回显出来。
运行效果及方法如下:
- 如图,打开运行输入cmd,先运行服务器程序1_13a_echo_server.py,注意要输入参数
--port=9900
,得到界面如下:
- 再打开一个命令窗口,运行客户端程序1_13b_echo_client.py,得到结果如下:
我们看到,服务器在9900端口启动了一个监听,客户端向9900端口发送了“Test message. This will be echoed.”,而后,被服务器分了5次,全部返回了,之所以分5次是由于接受缓存大小只有8个字节。
1. 服务器程序1_13a_echo_server.py
#coding=utf_8
'''
Created on 2017-2-26
@author: lenovo
'''
import socket
import sys
import argparse
host = 'localhost'
data_payload = 2048
backlog = 5
# backlog:积压;未完成的订货;这里特指待连接队列长度。
def echo_server(port):
#create a TCP socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#Enable reuse address/port
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#Bind the socket to the port
server_address = (host,port)
print "Starting up echo server on %s port %s" % server_address
sock.bind(server_address)
sock.listen(backlog)
# 服务器端可建立连接的客户端的队列长度为 backlog=5
# The backlog argument specifies the maximum number of
# queued connections and should be at least 1;
while True:
print "Waiting to receive message from client"
client,address = sock.accept()
data = client.recv(data_payload)
#The maximum amount of data to be received at once is specified by bufsize.
if data:
print "Data : %s" %data
client.send(data)
print "sent %s bytes back to %s" %(data,address)
client.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='socket server example')
parser.add_argument('--port',action="store",dest="port",type=int,required = True)
given_args = parser.parse_args()
port = given_args.port
echo_server(port)
2. 客户端程序1_13b_echo_client.py
'''
Created on 2017-2-27
@author: lenovo
'''
import socket
import sys
import argparse
host = 'localhost'
def echo_client(port):
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_address = (host,port)
print "Connecting to %s port %s" % server_address
sock.connect(server_address)
try:
message = "Test message. This will be echoed."
print "Sending %s" % message
sock.sendall(message)
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = sock.recv(8)
amount_received += len(data)
print "Received : %s" %data
except socket.errno, e:
print "Socket error: %s" %str(e)
except Exception, e:
print "Other exception: %s" %str(e)
finally:
print "Closing connection to the server"
sock.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='socket server example')
parser.add_argument('--port',action="store",dest="port",type=int,required=True)
given_args = parser.parse_args()
port = given_args.port
echo_client(port)
3. argparse用于参数的输入和解析
3.1 import argparse
Function: The argparse module makes it easy to write user friendly command line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.
—-使用argparse模块,可以轻松建立友好的命令行用户接口,即在用户没输入相关参数的情况下进行提示需输入参数。
3.2 argparse.ArgumentParser()
生成
ArgumentParser
对象
3.3 The add_argument() method
定义命令行参数如何被解析获取。
3.4 The parse_args() method
ArgumentParser.parse_args(args=None, namespace=None)
Convert argument strings to objects and assign them as attributes of the namespace. Return the populated namespace.
—-该方法用于从字符串中提取参数,提取的方法按照3.3所定义的参数解析方法。
4. socket对象的相关函数
4.1 socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections.
用于接收一个连接,接受连接的socket必须绑定到一个地址和端口用于连接。
The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.
4.2 socket.bind(address)
Bind the socket to address. The socket must not already be bound. (The format of address depends on the address family — see above.)
4.3socket.close()
Close the socket. All future operations on the socket object will fail. The remote end will receive no more data (after queued data is flushed). Sockets are automatically closed when they are garbage-collected.
4.4 socket.connect(address)
Connect to a remote socket at address. (The format of address depends on the address family — see above.)
4.5 socket.listen(backlog)
Listen for connections made to the socket. The backlog argument specifies the maximum number of queued connections and should be at least 1; the maximum value is system-dependent (usually 5).
设置服务器端可建立连接的客户端的队列长度。
4.6socket.recv(bufsize[, flags])
Receive data from the socket. The return value is a string representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.
从socket连接接受数据,并定义一次获取的最大数量。