Python套接字;从客户端接收服务器发送

时间:2016-06-20 17:02:11

标签: python sockets tcp

我正在尝试在主机上发送TCP / IP上的消息。这是有效的,但由于某种原因,只需要为客户端的每个新消息重新实例化套接字。例如,这是一个发送三个单独消息的基本客户端:

import socket


host = '127.0.0.1'

class Client:
    def __init__(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.sock.connect((host,12347))

    def send(self,message):
            self.sock.sendall(message)
    def close(self):
        self.sock.close()


if __name__ == "__main__":

    message1 = "I am message 1"
    message2 = "I am message 2"
    message3 = "I am message 3"

    #exp = Client()
    #exp.connect()

    for i in range(0,3):
        try:
            exp = Client()
            exp.connect()
            if i == 0:
                txt = message1
            elif i == 1:
                txt = message2
            elif i == 2:
                txt = message3
                exp.send(txt)
                exp.close()

            print i
            exp.send(txt)

        except:
            pass

和接收的服务器:

#!/usr/bin/env python

import socket


class communication:


  def __init__(self):
    try:

      host = '127.0.0.1'

      self.Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      self.Server.bind((host,12347))

      self.Server.listen(1)

    finally:

      print "setup finished"



  def recieve(self):

    (connection, client_address) = self.Server.accept()

    data = connection.recv(128)

    return data



  def close(self):

    self.server.close()





if __name__ == "__main__":



    exp = communication()



    while True:

        try:

            (connection,client_address) = exp.Server.accept()

            message = connection.recv(128)

        finally:

            print message



        if message == "I am message 3":

          exp.close()

您将看到我如何在for循环的每次迭代中重新调用Client类。这似乎是发送消息2和3所必需的。如果套接字在主代码的开头只与connect()函数一起实例化一次,那么服务器在第一条消息发送后挂起在recv()上。

我无法理解为什么会这样,并且套接字只需要在服务器端设置一次。我做错了什么,或者这是正常的吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

这比你想象的还要糟糕。看看你的服务器代码。 exp.Server.accept()接受来自客户端的连接,但connection.receive()完全忽略该连接并执行第二次self.Server.accept()。你忽略了一半的关系!

接下来,您的服务器只进行一次接收....即使您尝试在连接上发送更多消息,服务器也会忽略它们。

但你不能只添加一个recv循环。您的客户端和服务器需要某种方式来标记消息边界,以便服务器知道如何将它们拉出来。一些基于文本的系统使用新行。其他人发送服务器可以读取的消息大小或固定大小的头。例如,HTTP使用新行和数据计数的组合。

如果你想从头开始学习插座,只要知道它们很复杂,你就需要学习。有很多方法可以构建服务器,您需要了解权衡。否则,从XMLRPC到zeromq有很多框架可以为你做一些繁重的工作。