代码位置
https://github.com/duganlx/fopnp/tree/m/py3
简单的TCP服务器和客户端
文件位置:fopnp/py3/chapter03/tcp_sixteen.py
import argparse, socket
def recvall(sock, length):
data = b''
while len(data) < length:
more = sock.recv(length - len(data))
if not more:
raise EOFError('was expecting %d bytes but only received'
' %d bytes before the socket closed'
% (length, len(data)))
data += more
return data
def server(interface, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((interface, port))
sock.listen(1)
print('Listening at', sock.getsockname())
while True:
print('Waiting to accept a new connection')
sc, sockname = sock.accept()
print('We have accepted a connection from', sockname)
print(' Socket name:', sc.getsockname())
print(' Socket peer:', sc.getpeername())
message = recvall(sc, 16)
print(' Incoming sixteen-octet message:', repr(message))
sc.sendall(b'Farewell, client')
sc.close()
print(' Reply sent, socket closed')
def client(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print('Client has been assigned socket name', sock.getsockname())
sock.sendall(b'Hi there, server')
reply = recvall(sock, 16)
print('The server said', repr(reply))
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the server listens at;'
' host the client sends to')
parser.add_argument('-p', metavar='PORT', type=int, default=1060,
help='TCP port (default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p)
运行效果
# cmd1
python tcp_sixteen.py server ""
Listening at ('0.0.0.0', 1060)
Waiting to accept a new connection
We have accepted a connection from ('127.0.0.1', 13857)
Socket name: ('127.0.0.1', 1060)
Socket peer: ('127.0.0.1', 13857)
Incoming sixteen-octet message: b'Hi there, server'
Reply sent, socket closed
Waiting to accept a new connection
# cmd2
python tcp_sixteen.py client 127.0.0.1
Client has been assigned socket name ('127.0.0.1', 13857)
The server said b'Farewell, client'
可能造成死锁的TCP服务器和客户端
文件位置:fopnp/py3/chapter03/tcp_deadlock.py
import argparse, socket, sys
def server(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(1)
print('Listening at', sock.getsockname())
while True:
sc, sockname = sock.accept()
print('Processing up to 1024 bytes at a time from', sockname)
n = 0
while True:
data = sc.recv(1024)
if not data:
break
output = data.decode('ascii').upper().encode('ascii')
sc.sendall(output) # send it back uppercase
n += len(data)
print('\r %d bytes processed so far' % (n,), end=' ')
sys.stdout.flush()
print()
sc.close()
print(' Socket closed')
def client(host, port, bytecount):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
bytecount = (bytecount + 15) // 16 * 16 # round up to a multiple of 16
message = b'capitalize this!' # 16-byte message to repeat over and over
print('Sending', bytecount, 'bytes of data, in chunks of 16 bytes')
sock.connect((host, port))
sent = 0
while sent < bytecount:
sock.sendall(message)
sent += len(message)
print('\r %d bytes sent' % (sent,), end=' ')
sys.stdout.flush()
print()
sock.shutdown(socket.SHUT_WR)
print('Receiving all the data the server sends back')
received = 0
while True:
data = sock.recv(42)
if not received:
print(' The first data received says', repr(data))
if not data:
break
received += len(data)
print('\r %d bytes received' % (received,), end=' ')
print()
sock.close()
if __name__ == '__main__':
roles = ('client', 'server')
parser = argparse.ArgumentParser(description='Get deadlocked over TCP')
parser.add_argument('role', choices=roles, help='which role to play')
parser.add_argument('host', help='interface the server listens at;'
' host the client sends to')
parser.add_argument('bytecount', type=int, nargs='?', default=16,
help='number of bytes for client to send (default 16)')
parser.add_argument('-p', metavar='PORT', type=int, default=1060,
help='TCP port (default 1060)')
args = parser.parse_args()
if args.role == 'client':
client(args.host, args.p, args.bytecount)
else:
server(args.host, args.p)
运行效果
# cmd1
python tcp_deadlock.py server ""
Listening at ('0.0.0.0', 1060)
Processing up to 1024 bytes at a time from ('127.0.0.1', 13918)
195760 bytes processed so far
# cmd2
python tcp_deadlock.py client 127.0.0.1 160000000
Sending 160000000 bytes of data, in chunks of 16 bytes
391552 bytes sent