본문 바로가기
네트워크/소켓프로그래밍

[소켓 프로그래밍] 파이썬 소켓으로 파일 전송하고 받기 (TCP 통신에서 소켓을 close() 하는 것의 중요성)

by anjulia 2023. 6. 26.

https://foxtrotin.tistory.com/278

 

[파이썬] 소켓 프로그래밍-파일 전송, 파일 수신

이전 글에서 1:1 채팅 프로그램을 만들었다 (foxtrotin.tistory.com/272) 이번에는 소켓으로 파일을 보내는 프로그램을 만들어 본다 기본적인 내용은 1:1 채팅 프로그램 글에 있습니다 파일 처리 방법 파

foxtrotin.tistory.com

위의 블로그를 토대로 파이썬 소켓으로 파일 전송, 수신을 하고 있었다. 

 

그런데 파일 전송은 완벽하게 되는데, 수신이 안되는 문제점이 있었다. 

 

 

 

 

서버에서 파일 전송은 아래 사진처럼 완벽하게 되었다. 

 

 

 

그런데 클라이언트에서 파일 수신이 되지 않고 계속 코드가 돌아가고 있다. 

 

 

 

 

이유는 서버에서 accept함수에서 리턴된 소켓(통신 소켓)을 닫지 않아서 발생하는 문제이다. 

 

 

서버 코드 

from socket import *
from os.path import exists
import sys
import os 

serverSock = socket(AF_INET, SOCK_STREAM)
serverSock.bind(('',2267))

serverSock.listen(1)

con_sock, addr = serverSock.accept()

print(str(addr),'에서 접속 확인 ! ')


filename = con_sock.recv(1024)
print('클라이언트가 요청한 파일 : ', filename.decode())
data_transferred = 0

if not exists('./model_file/'+filename.decode()):
    print('파일이 없습니다.')
    sys.exit()

print("파일 %s 전송 시작" %filename)

now_dir = os.path.join('./model_file/', filename.decode())

with open(now_dir, 'rb') as f:
    try :
        data = f.read(4096)
        while data:
            data_transferred += con_sock.send(data)
            
            data = f.read(4096)
            
    except Exception as ex:
        print(ex)


print("전송 완료 %s 전송량 %d" %(filename, data_transferred))
con_sock.close() # 추가!!!

 

 

클라이언트 코드 

 

from socket import *
from os.path import exists
import sys
import os 
clientSock2 = socket(AF_INET, SOCK_STREAM)
clientSock2.connect(('127.0.0.1', 2267))

print('연결 성공! ')
#filename = '/server-global-eff-model.pth'
filename = 'server-global-eff-model.pth'
clientSock2.sendall(filename.encode())

data = clientSock2.recv(4096)
data_transferred = 0

if not data:
    print('파일 %s가 서버에 존재 하지 않음' %filename)
    sys.exit()

nowdir = os.getcwd()
save_dir = os.path.join(nowdir, filename)

print(save_dir)

with open(save_dir, 'wb') as f:
    try :
        
        while data:
            f.write(data)
            data_transferred += len(data)
            data = clientSock2.recv(4096)
    
    except Exception as ex:
        print(ex)

print("파일 %s 받기 완료 : 전송량 %d " %(filename, data_transferred))

clientSock2.close()

 

서버 쪽 통신 소켓을 닫아주면 이제 정상적으로 파일이 수신이 된다. 

 

 

 

이유는 다음에... 더 공부해서 작성하도록 하겠다!!!