老师留的作业,用Python写出来的,比C++简单的多 :-)
server端处理使用多线程,希望大家多多指教。
btw:恭喜neusoft过cmm5,呵呵。
编写一个基于TCP的服务器与客户程序
要求服务器能同时接收5个客户的连接请求
客户从键盘接收用户的输入,在回车后将用户输入的内容发送给服务器,服务器将接收的内容发回,客户方接收后再显示在用户的显示器上(即echo功能),当服务器方接收到exit这个串时,要发回byebye这个消息,然后退出,而客户方在接收到byebye这个消息后再退出。举例如下(客户方):
输入:hello
输出:hello
输入:enjoy socket programming!
输出:enjoy socket programming!
输入:exit
输出:byebye
服务器方的IP地址与端口要以参数的形式给出,如:
C:> tcpclient 202.118.1.60 1234
代码
[myphp]
import socket, sys
if __name__ == '__main__':
#处理参数
argv = sys.argv
if (len(argv)!=3) or (len(argv)==2 and argv[1]=='/?'):
print '>>>Useage:', argv[0], '<address> <port>'
sys.exit(0)
HOST = argv[1] #Server IP地址
PORT = int(argv[2]) #Server 端口
print '>>>HOST:', HOST
print '>>>PORT:', PORT
#打开socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print '>>>Fail to open socket!'
sys.exit(1)
print '>>>Socket opened...'
#连接
try:
sock.connect((HOST, PORT))
except socket.error:
print '>>>Fail to connect!'
sock.close()
print '>>>Socket closed...'
sys.exit(1)
print '>>>Socket connected...'
flag = 1 #循环标志
iReturnValue = 0 #系统返回值
#向Server发送信息并回显
while(flag):
msg = raw_input('>>>Input message: ')
if msg == '':
continue
if msg == 'exit':
flag = 0
#发送信息
try:
sock.send(msg)
except socket.error:
print '>>>Fail to send message!'
iReturnValue = 1
break
print '>>>Message sent :', msg
#接收信息
try:
msg = sock.recv(1024)
except socket.error:
print '>>>Fail to receive message!'
iReturnValue = 1
break
print '>>>Message received:', msg
#关闭socket,退出程序
sock.close()
print '>>>Socket closed...'
print 'Exit client program.'
sys.exit(iReturnValue)
import socket, threading
import sys, copy, time
iClientCount = 0 #客户端连接数
def ConnectThread(conn, addr):
"""
Function called by thread to deal with client connection
"""
global iClientCount #引用全局变量
sock = copy.copy(conn)
address = copy.copy(addr)
flag = 1
while(flag):
try:
msg = sock.recv(1024)
except socket.error:
print '>>>A 'receive' error happened! IP:', address[0],
'PORT:', address[1]
break
if str(msg) == 'exit':
msg = 'byebye'
flag = 0
try:
sock.send(msg)
except socket.error:
print '>>>A 'send' error happened! IP:', address[0], 'PORT:',
address[1]
break
iClientCount -= 1
print '>>>Disconnected with', address[0], 'at port', address[1]
print '>>>Total number of connections is', iClientCount
sock.close()
def ListenThread(sock):
"""
Function called by thread to listen a connection
"""
global iClientCount
while 1:
if iClientCount >= MAX_CLIENTS:
time.sleep(5)
continue
try:
conn, addr = sock.accept()
except socket.error:
print '>>>An 'accept' error happened!'
continue
iClientCount += 1
print '>>>Connecting from', addr[0], 'at port', addr[1]
print '>>>Total number of connections is', iClientCount
threading.Thread(target=ConnectThread, args=(conn, addr)).start()
if __name__ == '__main__':
argv = sys.argv
if (len(argv)>3) or (len(argv)==2 and argv[1]=='/?'):
print '>>>Useage:', argv[0], '[port=<port>]
[max=<max_clients>]'
sys.exit(0)
HOST = ''
PORT = 8006
MAX_CLIENTS = 5
for arg in argv[1:]:
if arg.startwith('port='):
PORT = int(arg[len('port='):])
elif arg.startwith('max='):
MAX_CLIENTS = int(arg[len('max='):])
print '>>>PORT:', PORT
print '>>>MAX_CLIENTS:', MAX_CLIENTS
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Fail to open socket!'
sys.exit(1)
print '>>>Socket opened...'
try:
sock.bind((HOST, PORT))
except socket.error:
print 'Fail to bind port!'
sock.close()
sys.exit(1)
print '>>>Socket binding...'
try:
sock.listen(MAX_CLIENTS)
except socket.error:
print 'Fail to listen!'
sock.close()
sys.exit(1)
print '>>>Socket listening...'
threading.Thread(target=ListenThread, args=(sock,)).start()
#此程序不能自己结束:-)
[/myphp]