Найти - Пользователи
Полная версия: tcp socket client: основы
Начало » Network » tcp socket client: основы
1
axe
беру из документации пример:
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print "%s wrote:" % self.client_address[0]
print self.data
self.request.send(self.data.upper())

if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
если в handle() прописать:
conn, address = self.socket.get_request()
то conn - это новый объект типа socket. Если его хранить, то соединение с клиентом не будет закрываться.
не пойму, как правильно работать с этим объектом.

т.е. к серверу коннектится несколько клиентов, соединение с каждым храниться. и через эти соединения могут отправлятся некоторые данные. с этим вроде понятно: проходим по списку и для каждого делаем conn.send().
а чтобы обрабатывать входящие в сокеты данные - нужно что-то придумывать более серьёзное. Возникает желание, чтобы вместо объекта socket в get_request приходил объект моего класса, унаследованного от socket. Это возможно?
Андрей Светлов
Можно переопределить TCPServer.get_request в потомке.
Наследоваться от socket - странная идея. Никогда не пробовал. Это же транспорт, а не протокол.
Я как-то для этих целей привык использовать twisted - а там все ясно и однозначно: Factory, Protocol, Transport.
axe
Пробую все входящие в MyTCPHandler.handle запросы собирать в список.

cсначала делаю:
poll = select.poll()
conn = self.request ## объект типа socket
fileno = conn.fileno()## в документации рекомендовано к использованию в select
poll.register( fileno, POLLIN|POLLPRI|POLLERR|POLLHUP )
и кладу в conn в список

потом прохожу по списку:
            iwtd, owtd, ewtd = select.select( [fileno], [], [fileno], 1 )
if iwtd > 0 and not ewtd:
data = conn.recv(1024)
и в результате ошибка:
Exception in thread Thread-3:
Traceback (most recent call last):
File “/usr/lib/python2.5/threading.py”, line 486, in __bootstrap_inner
self.run()
File “/usr/lib/python2.5/threading.py”, line 663, in run
self.function(*self.args, **self.kwargs)
File “./server_socket.py”, line 40, in hello
data = conn.recv(1024).strip()
File “/usr/lib/python2.5/socket.py”, line 146, in _dummy
raise error(EBADF, ‘Bad file descriptor’)
error: (9, ‘Bad file descriptor’)
что я делаю не так?
Андрей Светлов
Наверное, из списка еще и удалять нужно иногда :)
EBADF скорее всего говорит о том, что сокет уже закрыт.
Андрей Светлов
Еще непонятно, зачем вы пытаетесь мешать poll и select
axe
сокеты из списка удаляются в случае exception-а.
по поводу poll - я не особо умею им пользоваться. делаю по примеру. сейчас убрал его из совего тестового примера, - ничего не изменилось.

не понятно, почему сокеты закрываются.
т.е. если я получаю клиентский сокет через conn, addr = self.server.get_request(), то он живёт.
если я получаю через self.request, то соединение обрывается, не смотря на то, что объект продолжает существовать внутри списка.
axe
#!/usr/bin/python -t
# -*- coding: utf8 -*-

import SocketServer

from threading import Timer
from datetime import datetime
import sys
import select
f = open( '1.out', 'w' )
class F(object):
def __init__(self, f):
self.f = f

def write(self, x):
self.f.write(str(x)+"\n")
self.f.flush()

f = F(f)
class MySocket(object):
connList = []
def __init__(self, socket):
socket.makefile()
self.sock = socket
self.connList.append(socket)
sys.stdout = f
sys.stderr = f

@classmethod
def hello(cls):
for conn in cls.connList:
try:
fileno = conn.fileno()
iwtd, owtd, ewtd = select.select( [fileno], [], [fileno], 1 )
if iwtd > 0 and not ewtd:
data = conn.recv(1024).strip()
if data:
print data
conn.send(data.upper())
else:
f.write( "none" )
conn.send("none\n")
except Exception, e:
f.write(e)
cls.connList.remove(conn)
if not cls.connList:
f.write( "connList is empty" )
run()

def run():
t = Timer(2.0, MySocket.hello)
t.start()
run()

class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
MySocket(self.request)
self.request.settimeout(None)
print "new socket: ", self.client_address

HOST, PORT = "192.168.131.55", 9998
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
решил выложить полностью, чтобы в угадайку не играть
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB