파이썬 소켓 프로그래밍 관련 간단한 질문드립니다(서버클라 합쳐서 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라는 이미지를 보내고 서버에서 이미지를 수신한 후 수신 완료라는 메세지를 다시 클라이언트로 보내는 간단한 코드입니다.

문제는 클라이언트에서는 데이터를 정상적으로 전송하는데, 서버에서 데이터를 받는 도중 멈춰버린다는 것입니다.

소켓 프로그래밍에 대한 배움이 짧아 혼자서는 도저히 원인과 해결방법을 찾지 못했습니다. 고수님들의 도움 부탁드립니다.

  • while 문에 왜 루프 종료 조건이 없나요? 초보자 2021.7.28 09:16

1 답변

  • File 전송시에는 recv()가 종료되지 않고 계속 기다릴 수 있습니다(아니, 기다립니다)

    해결책으로는

    1. CLIENT에서 해당 파일의 SIZE를 먼저 주고, SERVER에선 그 SIZE 만큼 모두 Receive가 완료되면 recv() 종료
    2. CLIENT에서 socketclose() - SERVER에서 더이상 받을 메세지가 없음을 알게 함
    3. 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()
    
    • 아.. 질문이 벌써 14일이나 지난 ..... 안읽으실 수도있겠군요.. 나름 열심히 정리했는데... ;; whistler7899 2021.8.11 01:33

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)