老師留的作業,用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]
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]
>