파이썬 소켓 프로그래밍 관련 간단한 질문드립니다(서버클라 합쳐서 50줄 내외 간단한 코드입니다. )
조회수 777회
서버
import socket
HOST = ""
PORT = 8081
def receive(socket):
data = socket.recv(1024)
with open("D:/caps/test.jpg", 'wb') as f:
try:
while data:
f.write(data)
data = socket.recv(1024)
except Exception as e:
print(e)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
while True:
client_socket, addr = server_socket.accept()
receive(client_socket)
socket.send("수신 완료".encode())
클라이언트
import socket
HOST = '127.0.0.1'
PORT = 8081
def send():
data_transferred = 0
print("파일 전송 시작")
with open("E:/caps/test.jpg", 'rb') as f:
try:
data = f.read(1024)
while data:
data_transferred = client_socket.send(data)
data = f.read(1024)
if data_transferred == 0:
break
except Exception as e:
print(e)
def receive():
message = client_socket.recv(1024)
print(message.decode())
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, PORT))
send()
receive()
client_socket.close()
클라이언트에서 test.jpg라는 이미지를 보내고 서버에서 이미지를 수신한 후 수신 완료라는 메세지를 다시 클라이언트로 보내는 간단한 코드입니다.
문제는 클라이언트에서는 데이터를 정상적으로 전송하는데, 서버에서 데이터를 받는 도중 멈춰버린다는 것입니다.
소켓 프로그래밍에 대한 배움이 짧아 혼자서는 도저히 원인과 해결방법을 찾지 못했습니다. 고수님들의 도움 부탁드립니다.
1 답변
-
File 전송시에는
recv()
가 종료되지 않고 계속 기다릴 수 있습니다(아니, 기다립니다)해결책으로는
- CLIENT에서 해당 파일의 SIZE를 먼저 주고, SERVER에선 그 SIZE 만큼 모두 Receive가 완료되면
recv()
종료 - CLIENT에서
socket
을close()
- SERVER에서 더이상 받을 메세지가 없음을 알게 함 socket.shutdown(socket.SHUT_WR)
사용
이 있습니다.
본 질문의 코드는 파일송수신 완료 후에 SERVER에서 CLIENT로
수신 완료
메세지를 보내야 하기에 (socket connection을 닫으면 안되므로), 3번 해결책을 적용하였습니다.다른 좋은 방법이 있을 수 있겠지만, 저로서는 이게 최선이네요 ^
socket.shutdown(socket.SHUT_WR)
에 대해서는 stackoverflow 를 참고하시기 바랍니다.
SERVER SIDE
import socket HOST = "" PORT = 8081 def receive(receive_socket): with open("D:/caps/test.jpg", 'wb') as f: try: while True: data = receive_socket.recv(1024) if data: f.write(data) else: break except Exception as e: print(e) finally: f.close() if __name__ == '__main__': server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((HOST, PORT)) server_socket.listen(10) while True: client_socket, addr = server_socket.accept() receive(client_socket) # socket.send("수신 완료".encode()) : 오타? ㅎㅎ client_socket.send("수신 완료".encode())
CLIENT SIDE
import socket HOST = '127.0.0.1' PORT = 8081 def send(): with open("E:/caps/test.jpg", 'rb') as f: try: while True: data = f.read(1024) if data: client_socket.send(data) else: break # ------------------------------------ # client_socket.shutdown(socket.SHUT_WR) # ------------------------------------ # except Exception as e: print(e) def receive(): message = client_socket.recv(1024) print(message.decode()) if __name__ == '__main__': client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((HOST, PORT)) send() receive()
- CLIENT에서 해당 파일의 SIZE를 먼저 주고, SERVER에선 그 SIZE 만큼 모두 Receive가 완료되면
댓글 입력