2017-01-05 4 views
0

Я хочу слушать порт в Python3.Сокет в 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 -k -l -p 30003 | python3 script.py 

где script.py

while True: 
    for string in sys.stdin: 

Также мне нужно восстановить, если что-то не так, сервер должен быть готов принять все данные в любое время, так же, как nc -k -l -p 30003 | python3 script.py

ответ

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() 

Это должно быть хорошо, пока не упрется предел производительности. Существуют способы повышения эффективности (например, циклов событий), но я полагаю, что это выходит за рамки этого вопроса.

+0

Абсолютно то, что я хочу. Но есть некоторые проблемы: при первом подключении: 'nc localhost port Ctrl + C ' и скрипт закончен. Можно ли изменить его на все время? Спасибо. – user7365441

+0

@ user7365441 Вам просто нужно сказать, что ваш слуховой сокет «принять» навсегда (т. Е. В цикле 'while'). Я обновил ответ. – freakish

+0

Отлично! Спасибо! – user7365441