qingyun259 发表于 2022-12-7 20:20

Python的服务客户交互

今天跟着网课做了一下客户端以及服务端。
但是后续遇到了一个问题,在客户端与服务端进行交互的时候只有连接同一个局域网才能交互。
比方说两台电脑,一台连校园网,一台连手机热点就没有办法建立连接,请求各位泰斗帮看看问题出在哪里。
第一部分客户端代码:
import socketclass Client(object):
    def __init__(self):
      self.data = []

    def Initial_Client_Socket(self):
      # socket初始化

      connect_ip = input('请输入连接服务器的IP:')
      connect_port = int(input('请输入连接服务器的端口号:'))
      while True:
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.__Conncet_Sever(client_socket, connect_ip, connect_port)

            # 传输数据
            self.__Transport_Sever_Data(client_socket)

            # 接受客户端传输数据
            self.__Receive_Client_Data(client_socket)

            # 关闭客户端
            self.__Close_Clisent(client_socket)
            # 关闭会话
            self.__Close_chat()

    @staticmethod
    def __Conncet_Sever(client_socket, connect_ip, connect_port):
      client_socket.connect((connect_ip, connect_port))

    def __Transport_Sever_Data(self, client_socket):
      self.data = input('请输入要传输的的数据:').encode('GBK')
      client_socket.send(self.data)

    @staticmethod
    def __Receive_Client_Data(client_socket):
      recv_data = client_socket.recv(1024).decode('GBK')
      print(f'接收的数据为:\n{recv_data}')

    @staticmethod
    def __Close_Clisent(client_socket):
      client_socket.close()

    @staticmethod
    def __Close_chat():
      res = input('是否退出会话(Y/N):')
      if res == 'y' or res =='Y':
            exit()


if __name__ == '__main__':
    s = Client()
    s.Initial_Client_Socket()

服务端代码:

import socket


class Sever(object):
    def __init__(self):
      self.data = []

    def Initial_Sever_Socket(self):

      # socket初始化
      sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      # 重启服务器立刻释放地址和端口
      sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

      # 绑定端口
      self.__Bind_Sever(sever_socket)

      while True:
            # 设置监听
            self.__Listen(sever_socket)
            # 客户端等待连接,返回值为客户端的socket对象和客户端地址
            client_socket,ip_port = self.__Accept(sever_socket)

            # 接收客户端数据
            self.__Recv_Client_Data(client_socket,ip_port)

            # 给客户端发送数据
            self.__Transport_Client_Data(client_socket)
            # 关闭客户端
            self.__Close_Client(client_socket)

            # 关闭服务端
            self.__Close_Sever(sever_socket)


    @staticmethod
    def __Bind_Sever( sever_socket):
      while True:

            try:
                sever_ip = input('请输入绑定的IP(如果输入1则默认绑定本地主机IP):')
                sever_port = int(input('请输入绑定的端口号:'))
                if sever_ip == '1':
                  sever_ip = ''
                sever_socket.bind((sever_ip, sever_port))
            except BaseException as e:
                print('输入有误,请重新输入\n', e)
            else:
                break

    @staticmethod
    def __Listen( sever_socket):
      sever_socket.listen(128)

    @staticmethod
    def __Accept(sever_socket):
      client_socket, ip_port = sever_socket.accept()
      print(f'客户端{ip_port}使用端口{ip_port}连接成功')
      return client_socket, ip_port


    def __Recv_Client_Data(self,client_socket, ip_port):
      try:
            data = client_socket.recv(1024).decode('GBK')
            print(f'客户端{ip_port}发送的数据是:\n{data}...')
      except BaseException as e:
            print('远程主机强迫关闭了一个现有的连接,出现端口错误重新创建连接。。。\n')
            self.Initial_Sever_Socket()

    @staticmethod
    def __Transport_Client_Data(client_socket):
      data = input('请输入你想要发给客户端的数据:').encode('gbk')
      client_socket.send(data)

    @staticmethod
    def __Close_Client(client_socket):
      res = input('是否关闭客户端(Y/N):')
      if res == 'Y' or res == 'y':
            client_socket.close()

    @staticmethod
    def __Close_Sever(sever_socket):
      res = input('是否关闭服务端(Y/N):')
      if res == 'Y' or res == 'y':
            sever_socket.close()
            exit()

if __name__ == '__main__':

    s = Sever()
    s.Initial_Sever_Socket()

qingyun259 发表于 2022-12-8 07:16

顶顶顶顶顶顶

cloud2010 发表于 2022-12-8 11:57


ip 是如何得到的

qingyun259 发表于 2022-12-8 18:57

cloud2010 发表于 2022-12-8 11:57
ip 是如何得到的

绑定的是本地ip

繁华中的沉寂 发表于 2022-12-8 20:29

建议你学一下基本的网络知识,不在同一局域网内,必然无法交互。
如果想要不在同一局域网也能交互,至少保证服务端必须拥有固定的公网IP,且端口没有被封堵。
如果在拥有公网IP的路由器上,做个端口转发或许可行,但你这是校园网,显然无法自行配置。
你可以购买一台云服务器,将python服务端部署在云服务器上,并开放云服务器防火墙,云服务器IP一般都是固定的,这样你的客户端就能连上服务端。
或者你也可以尝试通过IPv6地址连接,但必须保证服务端和客户端都分配到了IPv6地址。

qingyun259 发表于 2022-12-8 20:32

繁华中的沉寂 发表于 2022-12-8 20:29
建议你学一下基本的网络知识,不在同一局域网内,必然无法交互。
如果想要不在同一局域网也能交互,至少保 ...

谢谢指导,受教了。
页: [1]
查看完整版本: Python的服务客户交互