파이썬 소켓 기반 채팅 프로그램을 제작하면서 공부했던 내용도 따로 정리해보았다.
https://hyobn.tistory.com/32
[파이썬] 채팅 프로그램 공부했던 내용
파이썬 멀티스레딩(Multi Threading) from threading import * x = Thread(target=yhb, args=('A',)) x.start() target : 쓰레드가 실행할 함수를 지정. args : target으로 지정한 함수에 넘길 인자. start() 함수..
hyobn.tistory.com
1. WinError 10038
[WinError 10038] 소켓 이외의 개체에 작업을 시도했습니다.
발생 원인 : 데이터 송수신 완료 전에 소켓을 close하면 발생한다.
해결 방법 : 코드에서 close() 함수를 사용한 위치 확인해보기. 적절한 위치에서 사용해야 한다.
2. WinError 10061
[WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
발생 원인 : ConnectionRefusedError로, 서버에 제대로 연결하지 못하였을 때 발생한다.
해결 방법 : 주로 서버의 ip주소나 port번호가 잘못 입력된 경우 또는 서버를 실행시키지 않은 경우 발생한다. 아래와 같이 client 코드 내에서 connect() 함수로 try except문을 구성하여 예외 처리하였다.
client_sock=socket(AF_INET, SOCK_STREAM)
try:
client_sock.connect((Host,Port))
except ConnectionRefusedError:
print('서버에 연결할 수 없습니다.')
print('1. 서버의 ip주소와 포트번호가 올바른지 확인하십시오.')
print('2. 서버 실행 여부를 확인하십시오.')
os._exit(1)
3. OSError: [Errno 98]
OSError: [Errno 98] Address already in use
발생 원인 : 주소 할당 에러, Binding Error. 이전에 실행했을 때 완전히 소멸되지 않은 소켓을 사용하려 할 때 발생한다.
(이에 대한 더 자세한 설명은 글의 상단에 있는 링크에 서술해놓았다.)
- 소켓의 SO_REUSEADDR 옵션 값을 1로 변경하여 Time-wait 상태에 있는 소켓에 할당되어 있는 PORT번호를 새로 시작하는
소켓에 할당되게끔 지정한다. 이 옵션의 default 값은 0이므로 아래의 구문을 추가적으로 적어줘야 한다.
server_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
4. Jupyter Notebook Dead-Kernel
커널이 죽는 이유 : Jupyter Notebook에 할당된 메모리가 낮아 크롬 등의 다른 메모리들과 충돌하기 때문
해결방법 :
1) Jupyter Notebook의 설정 파일 위치로 이동.
2) jupyter_notebook_config.py 파일 열기(메모장으로도 열 수 있다)
3) ctrl + f로 max_buffer_size 를 찾아 주석을 제거하고 default값을 기존의 값보다 크게 할당(10배 정도면 충분하다).
5. 출력 형식 문제점
terminal 창에서 실행했을 때, 입력 중에 메시지를 수신하면 입력 중이던 라인에 수신받은 메시지가 덧붙여져 출력된다.

위 사진은 나와 동진이의 대화인데 내가 '반갑습니다'를 입력하던 중 동진이가 메시지를 보내어 그 메시지가 덧붙여져 출력된 상황이다.
처음에 생각했던 방법은 캐리지 리턴('\r')을 활용하여 입력 중이던 라인을 다 지우고 수신받은 메시지만 출력시키는 것이었는데 그렇게 하면 기존에 입력 중이던 메시지가 버퍼에서 완전히 지워지는 것이 아니라 그대로 저장하게 된다. 즉, 입력했던 메시지가 눈에 보이는 화면에서만 사라지고 실제로는 다 저장되어 있기 때문에 send했을 때 화면에서 지워진 메시지도 같이 보내진다. 따라서 자신이 어떤 메시지를 입력했고 발신하게 되는지 명확하게 알기 어렵다.
위 사진을 예시로 들면 캐리지 리턴 방법을 적용시키면 두 번째줄의 '당신 : 반갑습니'는 터미널 상에서만 지워져서 '[13:56] 동진 : ㅎㅇㅎㅇ' 만 깔끔하게 출력되지만 그다음 내가 '다'만 입력해서 메시지를 전송해도 상대방에게는 기존의 '반갑습니'에 '다'가 합쳐진 '반갑습니다'가 전송되는 것이다.
이를 해결하기 위해 수신받은 메시지를 출력하고 그 다음 라인에 입력 버퍼에 저장되어 있는 메시지를 다시 출력하는 방법을 구상했지만 구현할 수 있는 마땅한 방법을 찾기가 힘들었다. c언어에는 입출력 버퍼에 접근할 수 있던데 파이썬은 막아놓은 것 같다. 아니면 내가 못 찾았거나...
고심에 빠져 있을 때 문득 떠올랐다. Jupyter Notebook에서는 이를 고려할 필요가 없다는 사실이.. 사용자에게 입력받는 input 칸과 실행 결과를 출력해주는 출력 칸이 분리되어 있어서 메시지 입력 중에 수신을 받아도 아무런 문제없이 출력 칸에 수신받은 메시지가 출력되었기 때문이다.
6. EOF 에러
EOFError:EOF when reading a line
사실 가장 오랫동안 삽질했던 에러이다. 초반에 사지방에서 goorm ide로 파이썬 컨테이너 만들어서 개발했을 때는 문제없이 잘 돌아가던 코드가 사무실에서 Jupyter Notebook으로 돌리니까 EOF 에러를 뱉어냈다. 두 환경 모두 파이썬 버전은 3.7.4로 동일했다.
input으로 사용자한테 메시지를 입력받아 send하는 과정에서 한 번 send하고 다시 input 받으려고 할 때 EOF 에러가 발생했다. 컴파일러 차이 때문인지 그 외 환경 차이인지 감이 안 잡혀서 고민하다가 코드가 그렇게 길지 않으니 완전 기초 서버-클라이언트 뼈대 코드에서부터 하나하나 코드를 더해가며 테스트해나갔다. (버전 관리의 중요성을 깨달을 수 있었다. 깃허브 최고!)
send_func의 try except문이 문제였다. 처음 메시지를 입력받아 보내는 것까지는 문제가 없었지만 그다음 다시 input을 받을 때 예외가 발생하여 바로 except문으로 넘어가는데, 이 코드들이 while true 안에 들어있기 때문에 EOF 에러 메시지가 끊임없이 출력되는 것이었다.
간단 후기
세상은 넓고 에러는 너무 많다.
'Project' 카테고리의 다른 글
[Spring] TipMI 프로젝트 정리 (1) | 2023.02.27 |
---|---|
[파이썬] 채팅 프로그램 제작하며 공부했던 내용 (2) | 2022.03.13 |
[파이썬] 채팅 프로그램 (2) | 2022.01.01 |
파이썬 소켓 기반 채팅 프로그램을 제작하면서 공부했던 내용도 따로 정리해보았다.
https://hyobn.tistory.com/32
[파이썬] 채팅 프로그램 공부했던 내용
파이썬 멀티스레딩(Multi Threading) from threading import * x = Thread(target=yhb, args=('A',)) x.start() target : 쓰레드가 실행할 함수를 지정. args : target으로 지정한 함수에 넘길 인자. start() 함수..
hyobn.tistory.com
1. WinError 10038
[WinError 10038] 소켓 이외의 개체에 작업을 시도했습니다.
발생 원인 : 데이터 송수신 완료 전에 소켓을 close하면 발생한다.
해결 방법 : 코드에서 close() 함수를 사용한 위치 확인해보기. 적절한 위치에서 사용해야 한다.
2. WinError 10061
[WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
발생 원인 : ConnectionRefusedError로, 서버에 제대로 연결하지 못하였을 때 발생한다.
해결 방법 : 주로 서버의 ip주소나 port번호가 잘못 입력된 경우 또는 서버를 실행시키지 않은 경우 발생한다. 아래와 같이 client 코드 내에서 connect() 함수로 try except문을 구성하여 예외 처리하였다.
client_sock=socket(AF_INET, SOCK_STREAM)
try:
client_sock.connect((Host,Port))
except ConnectionRefusedError:
print('서버에 연결할 수 없습니다.')
print('1. 서버의 ip주소와 포트번호가 올바른지 확인하십시오.')
print('2. 서버 실행 여부를 확인하십시오.')
os._exit(1)
3. OSError: [Errno 98]
OSError: [Errno 98] Address already in use
발생 원인 : 주소 할당 에러, Binding Error. 이전에 실행했을 때 완전히 소멸되지 않은 소켓을 사용하려 할 때 발생한다.
(이에 대한 더 자세한 설명은 글의 상단에 있는 링크에 서술해놓았다.)
- 소켓의 SO_REUSEADDR 옵션 값을 1로 변경하여 Time-wait 상태에 있는 소켓에 할당되어 있는 PORT번호를 새로 시작하는
소켓에 할당되게끔 지정한다. 이 옵션의 default 값은 0이므로 아래의 구문을 추가적으로 적어줘야 한다.
server_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
4. Jupyter Notebook Dead-Kernel
커널이 죽는 이유 : Jupyter Notebook에 할당된 메모리가 낮아 크롬 등의 다른 메모리들과 충돌하기 때문
해결방법 :
1) Jupyter Notebook의 설정 파일 위치로 이동.
2) jupyter_notebook_config.py 파일 열기(메모장으로도 열 수 있다)
3) ctrl + f로 max_buffer_size 를 찾아 주석을 제거하고 default값을 기존의 값보다 크게 할당(10배 정도면 충분하다).
5. 출력 형식 문제점
terminal 창에서 실행했을 때, 입력 중에 메시지를 수신하면 입력 중이던 라인에 수신받은 메시지가 덧붙여져 출력된다.

위 사진은 나와 동진이의 대화인데 내가 '반갑습니다'를 입력하던 중 동진이가 메시지를 보내어 그 메시지가 덧붙여져 출력된 상황이다.
처음에 생각했던 방법은 캐리지 리턴('\r')을 활용하여 입력 중이던 라인을 다 지우고 수신받은 메시지만 출력시키는 것이었는데 그렇게 하면 기존에 입력 중이던 메시지가 버퍼에서 완전히 지워지는 것이 아니라 그대로 저장하게 된다. 즉, 입력했던 메시지가 눈에 보이는 화면에서만 사라지고 실제로는 다 저장되어 있기 때문에 send했을 때 화면에서 지워진 메시지도 같이 보내진다. 따라서 자신이 어떤 메시지를 입력했고 발신하게 되는지 명확하게 알기 어렵다.
위 사진을 예시로 들면 캐리지 리턴 방법을 적용시키면 두 번째줄의 '당신 : 반갑습니'는 터미널 상에서만 지워져서 '[13:56] 동진 : ㅎㅇㅎㅇ' 만 깔끔하게 출력되지만 그다음 내가 '다'만 입력해서 메시지를 전송해도 상대방에게는 기존의 '반갑습니'에 '다'가 합쳐진 '반갑습니다'가 전송되는 것이다.
이를 해결하기 위해 수신받은 메시지를 출력하고 그 다음 라인에 입력 버퍼에 저장되어 있는 메시지를 다시 출력하는 방법을 구상했지만 구현할 수 있는 마땅한 방법을 찾기가 힘들었다. c언어에는 입출력 버퍼에 접근할 수 있던데 파이썬은 막아놓은 것 같다. 아니면 내가 못 찾았거나...
고심에 빠져 있을 때 문득 떠올랐다. Jupyter Notebook에서는 이를 고려할 필요가 없다는 사실이.. 사용자에게 입력받는 input 칸과 실행 결과를 출력해주는 출력 칸이 분리되어 있어서 메시지 입력 중에 수신을 받아도 아무런 문제없이 출력 칸에 수신받은 메시지가 출력되었기 때문이다.
6. EOF 에러
EOFError:EOF when reading a line
사실 가장 오랫동안 삽질했던 에러이다. 초반에 사지방에서 goorm ide로 파이썬 컨테이너 만들어서 개발했을 때는 문제없이 잘 돌아가던 코드가 사무실에서 Jupyter Notebook으로 돌리니까 EOF 에러를 뱉어냈다. 두 환경 모두 파이썬 버전은 3.7.4로 동일했다.
input으로 사용자한테 메시지를 입력받아 send하는 과정에서 한 번 send하고 다시 input 받으려고 할 때 EOF 에러가 발생했다. 컴파일러 차이 때문인지 그 외 환경 차이인지 감이 안 잡혀서 고민하다가 코드가 그렇게 길지 않으니 완전 기초 서버-클라이언트 뼈대 코드에서부터 하나하나 코드를 더해가며 테스트해나갔다. (버전 관리의 중요성을 깨달을 수 있었다. 깃허브 최고!)
send_func의 try except문이 문제였다. 처음 메시지를 입력받아 보내는 것까지는 문제가 없었지만 그다음 다시 input을 받을 때 예외가 발생하여 바로 except문으로 넘어가는데, 이 코드들이 while true 안에 들어있기 때문에 EOF 에러 메시지가 끊임없이 출력되는 것이었다.
간단 후기
세상은 넓고 에러는 너무 많다.
'Project' 카테고리의 다른 글
[Spring] TipMI 프로젝트 정리 (1) | 2023.02.27 |
---|---|
[파이썬] 채팅 프로그램 제작하며 공부했던 내용 (2) | 2022.03.13 |
[파이썬] 채팅 프로그램 (2) | 2022.01.01 |