2018년 1월 5일 금요일

python의 soocket 통신시 send()와 sendall()의 차이에 대해서





python의 soocket 통신시 send()와 sendall()의 차이에 대해서

Linux 시스템이 구동되는 임베디드 장비의 python과 Windows PC의 C#간 Socket통신을 하면서 임베디드 장비에서 binary 파일(이미지 파일)을 읽어서 Ethernet을 통해 PC로 전송하는 프로그램을 개발하다 보니 묘하게도 전송된 파일의 사이즈가 원본과 약간의 차이가 나는 것을 발견하게 되었다.
몇 byte에서 몇 십 byte까지...

로그를 출력해보면 데이터를 전송하는 쪽(python)에서 뭔가 모르게 데이터를 다 전송하지 못하는것 같았다. 이게 말이 되는지 모르지만 아무튼 전송된 파일의 파일 사이즈가 약간 적게 전송되는 기현상이 계속되었다.

결국은 python socket의 send()와 sendall()이 차이가 있음을 보게된다. 황당함~
Stackoverflow에 다음과 같은 설명이 있다.

https://stackoverflow.com/questions/34252273/what-is-the-difference-between-socket-send-and-socket-sendall

socket.send is a low-level method and basically just the C/syscall method send(3) / send(2). It can send less bytes than you requested, but returns the number of bytes sent.

socket.sendall is a high-level Python-only method that sends the entire buffer you pass or throws an exception. It does that by calling socket.send until everything has been sent or an error occurs.

If you're using TCP with blocking sockets and don't want to be bothered by internals (this is the case for most simple network applications), use sendall.

send()
 -. low-level에서 작동되는 시스템콜 형태
 -. 요청한 데이터보다 더 적게 전송할수도 있다.
 -. 그러나 요청한 만큼 전송한 걸로 return해 준다.

sendall()
 -. high-level단의 메소드로 python 메소드이다
 -. 요청한 데이터의 모든 버퍼 내용을 모두 전송한다. 그렇게 되지않을시 Exception발생
 -. sendall()도 내부적으로는 send()를 이용하는데 단지 모두 전송할 때까지 send()를 호출한다.

황당하지만 이렇다고 한다.
테스트해보면 5Mb정도의 이미지 파일을 전송해 볼때 sendall()이 send()보다는 확실히 속도가 좀 떨어지는 것 같다.

댓글 없음:

댓글 쓰기