Python中的Socket只发送接收到的数据

0 投票
1 回答
1012 浏览
提问于 2025-04-16 01:04

我觉得我的代码里可能漏掉了什么。我把一个“回声服务器”的例子改写了一下,让它在收到信息时能做更多的事情。

现在的代码看起来是这样的:


#!/usr/bin/env python

import select
import socket
import sys
import threading
import time
import Queue

globuser = {}
queue = Queue.Queue()

class Server:
    def __init__(self):
        self.host = ''
        self.port = 2000
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:
            inputready,outputready,exceptready = select.select(input,[],[])

            for s in inputready:

                if s == self.server:
                    # handle the server socket
                    c = Client(self.server.accept(), queue)
                    c.start()
                    self.threads.append(c)

                elif s == sys.stdin:
                    # handle standard input
                    junk = sys.stdin.readline()
                    running = 0

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    initialized=0

    def __init__(self,(client,address), queue):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
    self.queue = queue
    self.threads = []
        global globuser
        print 'Client thread created!'


    def run(self):
        running = 1
        while running:
            print 'While running client'
            data = self.client.recv(self.size)
            print 'Dit we receive data?'
            if data:
                print 'Data received!'
        print 'Fetching data from socket: ',
        if data[0] == 'I':
            print 'Initializing user: ' + data
            user = {'uid': data[1:6] ,'x': data[6:9], 'y': data[9:12]}
            globuser[user['uid']] = user
            print globuser
            initialized=1
            m=updateClient(user['uid'], queue)
            m.start()
            self.threads.append(m)
            self.client.send('Beginning - Initialized'+';')

        elif data[0] == 'A':
            print 'Client has received previous data: ' + data

        #On deactivation, nothing works.
                self.client.send(data+';')
                #print 'Client Data sent: ' + data
            else:
                print 'Closing'
                self.client.close()
                running = 0

    if self.queue.empty():
        print 'Queue is empty'
    else:
        print 'Queue has information: ',
        data2 = self.queue.get(1, 1)
        isdata2 = 1
        if data2 == 'Exit':
            running = 0
            print 'Client is being closed'
            self.client.close()

    if isdata2 == 1:
        print 'Sending data to client: ' + data2,
        self.client.send(data2)
        self.queue.task_done()
        isdata2 = 0

    time.sleep(1)

class updateClient(threading.Thread):

    def __init__(self,uid, queue):
        threading.Thread.__init__(self)
        self.uid = uid
        self.queue = queue
        global globuser
        print 'updateClient thread started!'

    def run(self):
        running = 20
        test=0
        while running > 0:
            test = test + 1
            self.queue.put('Test Queue Data #' + str(test))
            running = running - 1
            time.sleep(1)

        print 'Updateclient has stopped'



if __name__ == "__main__":
    s = Server()
    s.run() 

这个代码运行得很好,不过一直发送相同的数据再加上其他数据,感觉有点傻。

在代码的中间部分,你会看到:


        #On deactivation, nothing works.
                self.client.send(data+';')
                #print 'Client Data sent: ' + data

当我把 self.client.send(data+';') 这一行去掉,或者改成 self.client.send('something else;') 的时候,它就不工作了!客户端什么也收不到。

这个“data”变量有什么特别之处吗?我需要以某种方式格式化这个字符串吗?

1 个回答

2

这是你代码的一个整理过的、可以正常运行的版本!我自己测试过,虽然没有写单元测试。

原来的代码有一些语法错误和其他杂七杂八的问题,所以我做了一些调整。我假设这个协议是用 ; 作为分隔符的,因为每条消息的最后都会发送一个 ; 给客户端,不过原来的代码并没有进行这样的分隔。

from twisted.internet import reactor, protocol, task
from twisted.protocols import basic
from twisted.python import log
import sys

class ServerProtocol(basic.LineOnlyReceiver):
    delimiter = ';'

    def lineReceived(self, line):
        if line.startswith('I'):
            user = dict(uid=line[1:6], x=line[6:9], y=line[9:12])
            self.factory.users[user['uid']] = user
            log.msg(repr(self.factory.users))
            self.startUpdateClient()
            self.sendLine('Beginning - Initialized')
        elif line.startswith('A'):
            self.sendLine(line)
        else:
            self.transport.loseConnection()

    def _updateClient(self):
        if self._running == 0:
            self._looper.stop()
            return
        self._running -= 1
        self._test += 1
        self.sendLine('Test Queue Data #%d' % (self._test,))

    def startUpdateClient(self):
        self._running, self._test = 20, 0
        self._looper = task.LoopingCall(self._updateClient)
        self._looper.start(1, now=False)

class Server(protocol.ServerFactory):
    protocol = ServerProtocol
    def __init__(self):
        self.users = {}

if __name__ == '__main__':
    log.startLogging(sys.stderr)
    reactor.listenTCP(2000, Server())
    reactor.run()

撰写回答