TCP Server 实现 RPN计算器(Python)

 简单使用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
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值