2016-12-22 2 views
-1

Привет, сообщество stackoverflow, Я написал простой скрипт на основе сокетов на основе Python и выполнил его ~ 20 раз. 18 раз он делал то, что должен был делать, но 2 раза печатал несколько писем Рэндома.тот же скрипт python, но разные результаты

(Он должен был посылать и печатать каждую FOLDERNAME в определенной директории)

Сервер:

import socket 
import os 
import base64 

host = '' 
port = 6934 

s = socket.socket() 

s.bind((host, port)) 

s.listen(5) 

while True: 
    c, addr = s.accept() 

    req = c.recv(512) 

    print "%s has connected w REQ %s" %(str(addr), str(req)) 

    amount = len(os.listdir("./software")) 

    c.send(str(amount)) 
    print amount 

    for dir in os.listdir("./software"): 
     name = str(dir) 
     c.send() 
     with open("./software/"+dir+"/img.jpg", "rb") as image: 
      image.seek(0) 
      imageStr = image.read().encode("base64") 
      c.send(imageStr) 
      print "imageStr" 
     with open("./software/"+dir+"/text.txt", "r+") as desc: 
      desc.seek(0) 
      descStr = desc.read() 
      c.send(descStr) 
      print descStr 
    c.close() 
s.close() 

Клиент:

import socket 

class Connection(object): 
    def __init__(self, name, desc): 
     self.name = name 
     self.desc = desc 

objList = [] 

def fetcher(request): 

    host = "192.168.178.87" 
    port = 6934 

    s = socket.socket() 

    s.connect((host, port)) 

    s.send(request) 

    amount = int(s.recv(128)) 

    for i in range(0, amount): 
     name = s.recv(512) 
     content = s.recv(32768) 
     desc = s.recv(8192) 
     objList.append(Connection(name, desc)) 

def window(): 
    for i in objList: 
     print i.name 
     print i.desc 
    print "Window loop" 
def main(request): 
    fetcher(request) 
    window() 
main("greetings") 

Консоль вывода (I не изменилась все в коде)

('192.168.178.87', 56752) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56754) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56756) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56757) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56758) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56759) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56761) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56762) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56763) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56764) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56765) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56766) has connected w REQ greetings 
1 
imageStr 
Hallo 
('192.168.178.87', 56767) has connected w REQ greetings 
1 
imageStr 
Hallo 

Консоль вывода (я не изменил ничего в Кодексе) Клиент: (Причина я здесь ...)

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
oneQk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAJBzt 
JBztJBztJBztJBztJBztJBztJBztJBztJBztAAAkHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0k 
HO0AACQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7QAAJBztJBztJBztJBztJBztJBztJBzt 
JBztJBztJBztAAAkHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0AACQc7SQc7SQc7SQc7SQc 
7SQc7SQc7SQc7SQc7SQc7QAAJBztJBztJBztJBztJBztJBztJBztJBztJBztJBztAAAkHO0kHO0k 
HO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0AACQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7QAA 
JBztJBztJBztJBztJBztJBztJBztJBztJBztJBztAAA= 


Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 

Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
oneQk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAJBzt 
JBztJBztJBztJBztJBztJBztJBztJBztJBztAAAkHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0k 
HO0AACQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7QAAJBztJBztJBztJBztJBztJBztJBzt 
JBztJBztJBztAAAkHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0AACQc7SQc7SQc7SQc7SQc 
7SQc7SQc7SQc7SQc7SQc7QAAJBztJBztJBztJBztJBztJBztJBztJBztJBztJBztAAAkHO0kHO0k 
HO0kHO0kHO0kHO0kHO0kHO0kHO0kHO0AACQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7SQc7QAA 
JBztJBztJBztJBztJBztJBztJBztJBztJBztJBztAAA= 


Window loop 

C:\Users\LeEmpollon\Desktop\Cream>python cream.py 
one 
Hallo 
Window loop 

Я использую Windows 7 Professional 64bit, Python 2.7, оба скрипта были выполнены на одном компьютере, а также сценарии и папки находятся в том же каталоге:

folder 
-software 
--one 
---img.jpg (10x10px) 
---text.txt(contains the word "Hello") 
--creamserver.py 
--cream.py 

Спасибо за чтение :)

+0

где вы получаете свои магические числа из 'name = s.recv (512) content = s.recv (32768) desc = s.recv (8192)'? – corn3lius

+1

Похоже, вы просто отправляете кучу данных с отдельными вызовами 'send' и пытаетесь прочитать их отдельно с отдельными вызовами' recv', но это не сработает. Если два 'send' происходят до' recv', следующий 'recv' получит данные от обоих. См. [Сокет программирование howto] (https://docs.python.org/2/howto/sockets.html#using-a-socket). Это одна из причин, по которой люди обычно используют какой-то сетевой протокол вместо прямого взаимодействия с сокетами. Это боль в заднице. – BrenBarn

+0

@ corn3lius Я просто использовал некоторые цифры, которые казались достаточно большими для тех вещей, для которых я собираюсь их использовать. –

ответ

2

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

Если вы отправляете name, imageStr и desc, это то же самое, что и отправка всех трех из них в одну большую блоб. С другой стороны, ваш код клиента не может сказать, где заканчивается name, и начинается imageStr.

Периодический характер поведения обусловлен непредсказуемым сроком независимой работы клиента и сервера. Если вашему серверу удастся отправить как name, так и imageStr, прежде чем клиент выполнит свой recv, клиент получит оба одновременно. Если клиент совершает recv между отправкой двух частей данных, тогда recv получит только то, что было отправлено этой точкой. В вашем случае это похоже на то, что первое произошло дважды, а последнее произошло однажды.

Эти проблемы объясняются в Socket Programming HOWTO, которые вы должны прочитать. Особенно эта часть:

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

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

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

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