Python3中的套接字,监听端口

时间:2017-01-05 10:47:07

标签: python python-3.x sockets

我想在Python3中监听端口。

import socket

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

print 'connected:', addr

while True:
    data = conn.recv(1024)
    if not data:
        break
    conn.send(data.upper())

conn.close()

我想听的数据如下:

8,0,0,test,0,2016/07/19,14:40:57.938,2016/07/19,14:40:57.938,,,,,,,,,,,,0
8,0,0,test,0,2016/07/19,14:40:57.965,2016/07/19,14:40:57.965,,,,,,,,,,,,0
3,0,0,test,0,2016/07/19,14:41:04.687,2016/07/19,14:41:04.687,,2475,,,,,,,,,,0
..

我需要阅读'\n' 所以我需要改变这个块,但我不知道怎么做..

data = conn.recv(1024)
if not data:
    break
conn.send(data.upper())

我想替换nc:

nc -k -l -p 30003 | python3 script.py

其中script.py

while True:
    for string in sys.stdin:

如果出现问题我还需要重新连接,服务器必须随时准备好所有数据,就像nc -k -l -p 30003 | python3 script.py

一样

1 个答案:

答案 0 :(得分:0)

主要想法是阅读,直到您在流中找到\n字符。当然\n可能超出您正在阅读的1024字节,因此您需要将您在缓冲区中读取的所有内容存储起来。这可以用例如类:

来模拟
class SocketLineReader:
    def __init__(self, socket):
        self.socket = socket
        self._buffer = b''

    def readline(self):
        pre, separator, post = self._buffer.partition(b'\n')
        if separator:
            self._buffer = post
            return pre + separator

        while True:
            data = self.socket.recv(1024)
            if not data:
                return None

            pre, separator, post = data.partition(b'\n')
            if not separator:
                self._buffer += data
            else:
                data = self._buffer + pre + separator
                self._buffer = post
                return data

用法:

import socket

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)

conn, addr = sock.accept()

print('connected:', addr)

reader = SocketLineReader(conn)
while True:
    data = reader.readline()
    print(data)
    if not data:
        break
    conn.send(data.upper())

conn.close()

如果您希望服务器永久提供数据,请使用另一个while循环:

import socket

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)

while True:
    conn, addr = sock.accept()
    print('connected:', addr)
    reader = SocketLineReader(conn)
    # The other code goes here

这种方法的问题在于没有并行性。您的服务器不会处理并行连接。解决这个问题的一种方法是将每个新连接发送到一个单独的线程:

import socket
import threading

def handle(conn):
    print('connected:', addr)
    reader = SocketLineReader(conn)
    # The other code goes here

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)

while True:
    conn, addr = sock.accept()
    threading.Thread(target=handle, args=(conn,)).start()

这应该没问题,直到达到性能极限。有一些方法可以提高效率(例如事件循环),但我认为这超出了这个问题。