简单使用Python语言在TCP Server上实现了RPN计算器,默认端口号为65432
客户端通过建立TCP连接到服务器上用户指定的特定端口来发起请求。建立连接后,客户端将函数发送给服务器,服务器进行计算并返回结果。服务器一次只处理一个操作。服务器以FCFS方式服务客户端,每次只处理一个客户端,忽略它在服务客户端时收到的任何连接请求。
客户端和服务器通过发送ASCII消息进行通信。服务器向服务器发送RPN函数,服务器发送RPN函数的执行结果。
rpnserver.py
import socket
import sys
HOST='127.0.0.1'
BUFF_SIZE=1024
OVERFLOW='OVERFLOW'
if(len(sys.argv)<=1):
print ('Using default port number:65432')
PORT=65432
elif(len(sys.argv)==2):
PORT=int(sys.argv[1])
#initialize socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST,PORT))
while True:
#wait for client connection
s.listen(1)
conn,addr=s.accept()
print ("==============================================")
#keep receiving instructions from client
while True:
recv_str=conn.recv(BUFF_SIZE)
#send acknowledgement
if(recv_str==''):
conn.close()
break
out='Server Recieved:"'+recv_str+'"'
print (out)
#do the calculation
data=recv_str.split()
op1=int(data[0])
op2=int(data[1])
if data[2]=='+':
result=op1+op2
elif data[2]=='-':
result=op1-op2
elif data[2]=='*':
result=op1*op2
elif data[2]=='/':
if(op1*op2<0 and op1%op2!=0):#6/-132=0
result=op1/op2+1
else:
result=op1/op2
#OVERFLOW case
if(sys.getsizeof(result)>BUFF_SIZE):
conn.send(OVERFLOW)
else:
conn.send(str(result))
rpnclient.py
import socket
import sys
HOST='127.0.0.1' #server's hostname or IP address
PORT=int(sys.argv[1]) #server port
BUFF_SIZE=1024
OVERFLOW='OVERFLOW'
#initialize client
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
if(len(sys.argv)<3):
print ('No input function.')
sys.exit()
input_str=sys.argv[2].split()
stk=[]
for cnt in range(len(input_str)):
c=input_str[cnt]
if(c.lstrip('-').isdigit()):
stk.append(int(c))
if(cnt==len(input_str)-1):
print ("Input syntex error: no enough operators.")
else:
if(len(stk)<2 or (c!='+' and c!='-' and c!='*' and c!='/')):
print ('Input syntex error at',c)
s.close()
break
num2,num1=stk.pop(),stk.pop()
if(c=='/' and num2==0):
print ('Can not devide by 0.')
s.close()
break
string=str(num1)+' '+str(num2)+' '+c
if(sys.getsizeof(string)>BUFF_SIZE):
print ('Exceeds buffer size.')
s.close()
sys.exit()
s.send(string)
#wait for server to calculate
result=s.recv(BUFF_SIZE)
#overflow
if(result==OVERFLOW):
print ('Result exceeds buffer size.')
s.close()
else:
if(cnt==len(input_str)-1):
out='Client Received Final:'+result
if(len(stk)!=0):
print ('Input syntex error: no enough operators.')
print (out)
s.close()#send a NULL string to server
else:
out='Client Received:'+result
print (out)
stk.append(int(result))
——客户端
客户端每次处理一个RPN函数,计算完成后立即退出程序并显示结果。当它关闭套接字时,它向服务器发送一个EOF消息。客户端是无状态的。
——服务器
服务器有四种状态:等待客户端,等待功能,计算和关闭。
等待客户端-服务器侦听端口并等待连接请求。它建立了与第一个来的客户的联系。
Waiting for function—在此状态下,服务器侦听来自客户端的请求。在接收到函数消息时,它转换为计算格式。当服务器收到EOF消息时,它关闭连接并切换到等待客户端模式。
计算-服务器读取输入函数,计算并将结果返回给客户端。然后返回到等待函数模式。
关闭-用户可以关闭服务器,只要他们想按^c。
sample:
sample1
sample2
sample3
sample4
sample5
sample6