2013-05-11 6 views
4

Я пробовал искать ответ, но я не могу найти ответ, который отвечает на мою конкретную проблему.Клиентский сокет не принимает данные правильно

Возможно, я не знаю, как правильно сформулировать проблему.

Я думаю, что я точно определил, что это такое, но дело в том, что я просто не знаю, как это исправить.

EDIT: Я пытался использовать два клиента на одном разъеме TCP. Не могу этого сделать. Мне придется подумать о другом. Решил, наверное.

Так что у меня есть это

1: Два Клиенты

2: Один сервер

Цель заключается в следующем: ли сервер распространять новые имена пользователей для всех клиентов по мере их подключения.

Это то, что происходит, когда я запускаю программу:

сервера: Определение хоста и порта, его инициализации. Проверить

Клиент 1: Подключается к серверу. Проверить

Клиент 1: После подключения отправляет строку на сервер. Проверить

Сервер: Получает строку, проверяет, является ли строка в списке создается. Если это: Pass, если это не так, отправьте всем новую строку. Проверить

Client 1: [Теперь жду, чтобы получить данные] Recieves данные, проверяет, является ли строка полученной совпадающей с его послала. Если это так, напечатайте («Это один из наших!»), Иначе добавьте новую строку = в Имя клиента 2. Проверить

Клиент 2: Подключение к серверу: Check

Сервер: [Если он получает строку, печатает его.] (Работы) Проверяет, является ли новая строка в списке , [Это не так] Он отправляет новое имя пользователя всем, а затем печатает («Отправлено всем») Check

Но, когда клиент 2 получает строку, она печатает ее. Однако клиент 1 никогда не возвращает строку.

И при запуске клиента один в IDLE я заметил, что что-то пошло не так, поскольку клиент 1 попытался получить данные. (Цикл while, в котором данные = s.recv начал зацикливаться очень быстро, вместо того, чтобы ждать)

Я спросил в чате, но кажется, что вокруг никого нет. Я пробовал это посмотреть, но я действительно не могу найти ответ. Я подозреваю, что когда мой сервер отправляет «соединение» во второй раз, он как-то переопределяет исходное клиентское соединение.

Вот мой код сервера:

from socket import * 
import threading 
import os 
import csv 

Username_List = [] 

host = input("Host: ") 
port = input("Port: ") 

ss = socket(AF_INET,SOCK_STREAM) 
ss.bind((host,int(port))) 
ss.listen(2) 




while True: 
    try: 
     connection,address = ss.accept() 
     data = connection.recv(1024) 
     if data: 
      translated_data = data.decode() 
      print(translated_data) 

      if translated_data in Username_List: 
       pass 
      else: 
       Username_List.append(translated_data) 
       connection.sendall(translated_data.encode()) 
       print("Sent new username to everyone") 
    except IOError: 
     connection.close() 
     print("An exception with a connected user occured") 
     break 

И вот мой код клиента: [Единственное различие между клиентом 1 и 2, я изменил переменное имя пользователя]

# Sample Username Client Service Handler. 
from socket import * 
import threading 
import os 
import csv 

Username = ("Owatch") 
host = input("Host: ") 
port = input("Port: ") 
try: 

    ss = socket(AF_INET,SOCK_STREAM) 
    ss.connect((host,int(port))) 
except IOError: 
    print("Aw no man") 

ss.send(Username.encode()) 

while True: 
    try: 
     print("Waiting to Recieve Data") 
     data = ss.recv(1024) 
     if data: 
      translated_data = data.decode() 
      print(translated_data) 
      if translated_data == Username: 
       print("It's one of ours!") 

      else: 
       Client_Username = translated_data 
       print (Client_Username) 


    except Exception as e: 
     print (vars(e)) 

Если бы вы, пожалуйста, Я был бы благодарен.

Если вы знаете ответ на мой вопрос, который уже был задан, сообщите мне, и я удалю это сообщение, чтобы не нарушать правила. Благодаря!

+0

* Я просто заметил ошибку в своей логике. Если пользователь подключается за другим. Он не получит имя пользователя первого пользователя. Но первый разъем (?) Будет. Что-то мне придется исправить позже .. – Micrified

+0

Я считаю, что мой сервер не может обрабатывать два клиента на одном сокете. – Micrified

+0

Существует не такая вещь, как два клиента на одном сокете в TCP. – EJP

ответ

1

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

SERVER !!!

import csv 

class client(threading.Thread): 
    Username_List = [] 
    def __init__(self, conn): 
     super(client, self).__init__() 
     self.conn = conn 

    def run(self): 
     print "Client thread started" 
     data = self.conn.recv(1024) 
     print "Received: {0}".format(data) 
     if data in client.Username_List: 
      self.send_msg("Welcome Back!") 
     else: 
      for cnt in threadz: 
       cnt.send_msg(data) 
      print("Sent new username to everyone") 
      client.Username_List.append(data) 
     while True: 
      # dont need nothing now 
      pass 

    def send_msg(self,msg): 
     self.conn.send(msg) 

host = input("Host: ") 
port = input("Port: ") 

ss = socket() #AF_INET,SOCK_STREAM) 
ss.bind((host,int(port))) 
print "Server Opening on port: {0}".format(port) 
ss.listen(2) 
threadz = [] 
print "Begining Wait for connections" 

while True:  
    try: 
     connection, address = ss.accept() 
     print "Got ONE!" 
     c = client(connection) 
     print "Recevied connection from:{0} On port:{1}".format(address[0],address[1]) 
     c.start() 
     threadz.append(c) 
     print "Client appended to threadz, currently {0} threadz active".format(len(threadz)) 

    except IOError,KeyboardInterrupt: 
     connection.close() 
     print("An exception with a connected user occured") 
     break 

КЛИЕНТ:

# Sample Username Client Service Handler. 
from socket import * 
import threading 
import os 
import csv 

Username = ("ShyGuy") 
host = input("Host: ") 
port = input("Port: ") 
try: 
    ss = socket() #AF_INET,SOCK_STREAM) 
    ss.connect((host,int(port))) #I was using ("localhost",1234) for testing 
    ss.send(Username) 
except IOError: 
    print("Aw no man") 


print("Waiting to Recieve Data") 
while True: 
    try: 
     data = ss.recv(1024) 
     if data: 
      translated_data = data.decode() 
      print(translated_data) 
      if translated_data == Username: 
       print"Name: {0} has been registered on server!".format(translated_data) 
      else: 
       Client_Username = translated_data 
       print "New client name received: {0}".format(Client_Username) 


    except Exception as e: 
     print (vars(e)) 

Это работает на Python 2.7 с двумя клиентами на местном уровне. Необходимо использовать семафор для остановки печати нитей одновременно с печатью основного сервера: http://en.wikipedia.org/wiki/Semaphore_(programming)

Этот код не делает ничего изящного с отключением клиента, но как только вы сможете работать с исключениями, которые возникают при этом, происходит «Конечно, вы узнаете еще кое-что.

+0

Так жаль, получил ваше сообщение в чате. Случилось так, что я получил это, пока я работал над другим решением. Поэтому я думал, что добавлю его в закладки и вернусь к нему позже. (На самом деле хотел решить ее сам). В конце концов, я привязался к работе, и когда я вернулся, я вижу ваше сообщение. Так жаль. Я позабочусь о том, чтобы отложить всю работу, когда я доберусь до этого, и обновить вас снова. Единственное, что меня беспокоило, это то, что кто-то сказал мне, что открытие новых потоков для клиентов - плохая практика. Но учитывая, что я все это делал. Это не имеет значения. Большое спасибо человеку. Комментарий назад скоро! – Micrified

+0

Сладкий, не хотел больше преследовать вас в чате, если вы хотите что-то выяснить, я помог! – Noelkd

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