2017-05-11 7 views
1

비슷한 질문이 제기되었지만 나에게 효과가없는 것 같습니다. 사전을 직렬화하여 문자열로 변환 한 다음 소켓을 통해 보내기 전에 문자열을 변환하려고했습니다. 지금까지 성공하지 못했습니다!파이썬에서 소켓을 통해 사전을 어떻게 보냅니 까?

이 내 서버 코드 : #library 수입 소켓 수입 피클

소켓 초기화
#socket initialization 
host = "127.0.0.1" 
port = 5000 
mainAddr = (host, port) 

#dict initialization 
dataDict = {} #just imagine that dict has content 

#create socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP 
s.bind((mainAddr)) 
s.listen(4) 
print('program started') 
print('listening..') 

while True: 
    try: 
     conn, addr = s.accept() 
     print("connection from: "+str(addr)) 
     print("sending message..") 
     pickle.dumps(dataDict) 
     print('pickled!') 
     dataS = str(dataP) 
     print('stringed!') 
     dataE = dataS.encode('UTF-8') 
     print('encoded!') 
     s.sendto(dataE,addr) 
     print('data sent!') 
    except: 
     pass 

s.close() 

, 내가 해봤 다른 유형 : 보내는 부분에 대한

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP 
s = socket.socket() 

, 나는이 대안을 시도했다 :

s.send(dataE) 
s.send(dataE,addr) 
s.sendall(dataE) 
s.sendall(dataE,addr) 
나는이 프로그램을 실행하면

, 이러한 인쇄 얻을 :

program started 
listening.. 
connection from:<insert addr here> 
sending message.. 
pickled! 
stringed! 
encoded! 

data sent!는 전송되지 않습니다. 그래서 나는 그것이 문제가있는 전송 부분이라고 추측합니다.

#library 
import socket 
import pickle 

#initialization 
host = '127.0.0.1' 
port = 5000 
buffer = 1024 

#create socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP 
s.connect((host,port)) 
print('connected!') 

#receive dictionary 
print('receiving message..') 
while True: 
    data, addr = s.recvfrom(buffer) 
    print('received!') 
    dataD = data.decode("UTF-8") 
    print('decoded!') 
    dataP = pickle.loads(dataD) 
    print('unpickled!') 
    print(str(dataP)) 

s.close() 
클라이언트 단말기에서

만 다음 인쇄 : 클라이언트 측에 대한

는, 여기에 코드의 클라이언트 측에

connected! 
receiving message.. 

, 나는의 순서를 변경 시도했습니다 unpickling 및 디코딩하지만 여전히 유용합니다.

+0

이것은 실제 코드가 아닙니다. 기능 코드를 게시하십시오. –

+0

문제에 대한 접근 방법에 주목할 때 pickled 객체는 바이너리입니다. 당신은 그들을 str로 변환하고 있습니다 ... 그리고 나서 utf에서 인코딩합니다. 이것은 완전히 난센스입니다. 소켓은 바이너리이므로 소켓을 통해 pickle에서 반환 된 원시 바이트 스트림을 보낼 수 있습니다. 그냥 문제를 직면하면 그것을 단순화하고 반환하려고하십시오 :) –

+0

와우! 그냥 절인에 대한 제안을 해주셔서 감사합니다! 마침내 내 코드가 작동합니다! 이 답변과 아래의 답변은 도움이되었습니다. – ziggy

답변

1

TCP 서버 소켓은 데이터 송수신에 실제로 사용되지 않습니다. s.send() 또는 그와 비슷한 것을 호출 할 때 오류가 표시되지 않는다는 것에 놀랐습니다. 대신 코드에 서버에 연결하는 각 클라이언트의 개별 소켓을 생성하는 팩터 (conn)입니다. 따라서 conn.sendall()을 사용해야합니다. 주소 매개 변수는 필요하지 않으며 개별 소켓은 이미 대화 대상을 알고 있습니다. (.send()은 약간의 추가 작업 없이는 신뢰할 수 없습니다. .sendto()은 특정 클라이언트에 연결되지 않은 UDP 소켓에서만 사용됩니다.)

+0

감사! 그랬어! 가'보십시오 : 이것은 서버 측에 쓴 것입니다 CONN, ADDR = s.accept() 이 DATAP = pickle.dumps (dataDict가) #dataDict 내가 conn.sendall를 보낼 사전입니다 (DATAP) ' 난 str' 및 인코딩 부 '인코딩'로 타입 캐스팅을 벗고() '클라이언트 측 :. '참 동안 : 데이터 ADDR = s.recvfrom (버퍼) DATAP = 클 .로드 (데이터) 인쇄 (DATAP)' 나는 클라이언트와 서버 모두에 대해 소켓의 생성에 이런 짓을하는 것도 언급한다 : 's의 = socket.socket는()'이 의 그! 모두 4 개의 도움을 주셔서 감사합니다! – ziggy