2013-08-27 2 views
1

Я был самообучающимся python с нескольких месяцев, и, наконец, изучал программирование сокетов. В качестве учебного пособия я должен создать полудуплексную систему чата. Ниже приведен код. Первый запрос и ответ просто прекрасны, но каждый раз, когда я пытаюсь отправить второе сообщение от клиента, кажется, что сервер висит. Программа основана на TCP.Python: Socket Programming: accept() и connect calls

Я подозреваю, что, поскольку ss.accept() вызывается каждый раз, когда нужно послать новое сообщение, создается новый поток, но поскольку я сделал только один вызов sc.connect() от клиента, будь мое новое соединение на сервере, висит там бесконечно.

В след: я назвал ss.accept() вне цикла в то время, то есть делает только 1 подключение и прослушивание данных снова и снова на время цикла, разговоры работает просто отлично

Может кто-то пожалуйста, есть посмотрите код и помогите мне понять, в чем именно проблема.

Поскольку, я учусь, я еще не перешел на изгиб. Я хочу сначала изучить все основы, прежде чем перейти к рамкам.

 !bin/usr/env python 

import socket, sys 
HOST ='' 
PORT = 1060 
ADDR =(HOST,PORT) 

def userinput(sock): 
    usermessage = input('>') 
    sock.sendall(str(len(usermessage))) 
    return usermessage 


def server(): 
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 
    s.bind(ADDR) 
    s.listen(1) 
    print 'the server is listening at',s.getsockname() 

    while True: 
     ss,sockname = s.accept()  
    #listen to determine the bytes sent by client 
     msglen = ss.recv(4096) 
    #accept the complete message 
     msg = ss.recv(int(msglen)) 
     print 'client:', repr(msg) 
     servermsg = userinput(ss) 
     ss.sendall(servermsg) 
     print " ---------------" 
    ss.close() 

def client(): 
    sc = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    sc.connect(ADDR)  
    while True: 
     message = userinput(sc) 
     sc.sendall(message) 
     replylen = sc.recv(4096) 
     reply = sc.recv(int(replylen)) 
     print "reply:",reply 

     print "----------------" 
    sc.close() 

if sys.argv[1:] == ['server']: 
    server() 

elif sys.argv[1:] == ['client']: 
    client() 
else: 
    print >> sys.stderr,'usage:tcp_2_7.py server|client[host]' 

ответ

1

Ваша пробная версия - прием один раз, а затем получение нескольких сообщений - вот как вы должны это делать. Вызов accept ждет нового соединения - вам не нужно делать это каждый раз, когда вы хотите отправить или получить сообщение, так же, как вы не хотите звонить connect каждый раз, когда хотите отправить или получить.

Подумайте об этом так:

При подключении к серверу чата, вы подключаетесь, отправить сообщение, а затем отключить сразу? Нет. У вас есть постоянное открытое соединение, через которое отправляются сообщения, и соединение закрывается только в конце сеанса чата.

Из документов на accept:

socket.accept()

Принять соединение. Розетка должна быть привязана к адресу и прислушиваться к соединениям. Возвращаемое значение представляет собой пару (conn, address), где conn - новый объект сокета, который можно отправить, и получают данные о соединении, а адрес - адрес, связанный с сокетом на другом конце соединения.

+0

@ Jozzas: Спасибо за это быстрое объяснение! так что у меня есть несколько клиентов, то есть когда я буду вызывать accept и connect in loop для каждого клиента, сеанс сервера. – durga

+0

@durga Да! Абсолютно. Библиотеки, такие как twisted, могут сделать это намного проще, управляя пулом подключений, а не вам самому делать это самостоятельно. Это хорошо понять. – jozzas

Смежные вопросы