python 소켓을 통한 이미지 전송 시 문제
글쓴이: cat90129 / 작성시간: 일, 2016/09/04 - 4:39오후
안녕하세요, 파이카메라를 이용한 프로젝트 진행 중에 있는 학생입니다.
파이카메라와 소켓통신을 이용해서 작업을 진행하는데
1. 노트북(Server)에서 데이터를 전송합니다.
2. 파이(Client)에서 데이터를 받습니다.
3.특정한 값을 받으면 picamera가 동작을 해서 사진을 찍습니다.
4. 그리고 나서 이미지를 파일 형태로 만들어서 노트북에 파일을 전송합니다.
5. 이미지파일을 받은 노트북에서 파일을 실행 시켜서 이미지를 창에 띄웁니다.
이 작업 확인결과 '이부분에서 파일을 열어 볼 권한이 없는것 같습니다' 라는 문구와 함께 문제가 발생합니다.
제가 일주일간 곰곰히 생각해보면서 시도해 본 결과 파이쪽에서 소켓을 닫아야지만 노트북 쪽에서 파일을 다 받았다 판단을 하고 파일을 열 수 있더군요.
헌데 파이에서 소켓을 닫아버리면 계속 진행되는 server에서 pi로의 이 후 데이터 전송이 안되기에
문제가 생깁니다.
소켓을 닫지 않고 파일을 전송하고 끝난 후 자연스럽게 다시 데이터 전송이 되도록 할 수 있으면 좋겠습니다.
좋은 방법 아시는 분 계시면 감사하겠습니다.
server 쪽 코드입니다.
(어떤 데이터를 보냈을 때 파이에서 찍힌 이미지 파일을 받는 부분)
try: while True: #데이터를 보내는 코드 #특정데이터를 보냈을 시 이미지 받는 아래의 코드 실행 # hs - camera f = open('hstest.jpg','wb') image = connection.recv(buf) while(1): if image: print "1" f.write(image) image = connection.recv(buf) print "Receiving..." else : print "Done." break print "break complete." f.close() print "file close." webbrowser.open('hstest.jpg')
client(파이)
while True: try: #서버에서 보내는 데이터를 받습니다. curr_data_3 = unpacker.unpack(data)[2] if curr_data_3 is 1: #데이터가 1 일때 아래의 카메라 동작 실행 #camera start with picamera.PiCamera() as camera: time.sleep(0.5) camera.capture('hstest.jpg') buf = 1024 f = open('hstest.jpg', 'rb') image = f.read(buf) while(1): if image: print 'Sending...' sock.send(image) image = f.read(buf) else: print 'Done sending' break time.sleep(0.5) f.close() print 'file closing complete' #sock.close() #를 해야 파일이 열린다. 하지만 소켓 연결이 끊어져서 #연속적으로 다음 데이터를 받지를 못한다.
고수님들 부탁드립니다. ㅠ
Forums:
추정하건데, 클라이언트에서 파일의 마지막 부분을
추정하건데, 클라이언트에서 파일의 마지막 부분을 보내면, 서버에서
를 실행하고 계속 다음 패킷을 대기하는 중이라서 f.close()가 실행이 안 되고, 서버에서 이미지파일을 열어볼 수 없는 상태가 되는 것 같습니다.
해결은 다음처럼 하면 될 것 같습니다.
클라이언트에서 파일을 보낼 때, 파일 내용을 보내기 전에 몇 가지 정보(예를 들어 파일 크기)를 먼저 보냅니다.
서버에서는 파일 크기만큼 데이터를 받으면 f.close()를 실행하고 다음 파일을 받을 준비를 합니다.
감사합니다. 파일내용을 보내기 전에 파일크기를
감사합니다. 파일내용을 보내기 전에 파일크기를 보내려면 일단 capture 한 후 그 파일의 크기를 서버로 보내야하는데 그 크기를 추출하는 함수를 찾을 수가 없습니다. 방법을 알 수 있을까요?
이걸 찾으시나요? os.path.getsize
이걸 찾으시나요? os.path.getsize
https://www.google.co.kr/search?q=python+%ED%8C%8C%EC%9D%BC+%ED%81%AC%EA%B8%B0+%ED%99%95%EC%9D%B8&rlz=1C1ASRM_enKR557KR557&oq=python+%ED%8C%8C%EC%9D%BC+%ED%81%AC%EA%B8%B0+%ED%99%95%EC%9D%B8&aqs=chrome..69i57.3881j0j7&sourceid=chrome&ie=UTF-8
Signature :) - "여유를 갖고 행동하되 게을러지지 말자"
감사합니다. 덕분에 파일사이즈 값을 서버로 보내서 그
감사합니다. 덕분에 파일사이즈 값을 서버로 보내서 그 만큼 버퍼로 만드는것까지 완성했습니다.
파일을 닫는 f.close()를 한후 파일이 아닌
파일을 닫는 f.close()를 한후 파일이 아닌 그냥 데이터를 SERVER쪽에서 전송할 때도 위의 프로토콜을 구현하면 그냥 f.close()까지만 써도되는 건가요?
파일 사이즈 값을 서버로 보내서 서버에서 그 값만큼
파일 사이즈 값을 서버로 보내서 서버에서 그 값만큼 버퍼를 만드는 것 까지 완성했는데요.
헌데 아직도 소켓을 닫기 전까지 파일이 열리질 않습니다.
끝나는 시점까지 알려줘서 어떤 문구를 보내고 그 문구가 왔을 시 f.close()를 하려하는데 어려움이 있습니다. 서버나 클라이언트나 f.close()로 파일전송을 완료 시키고 다음 데이터 전송을 계속 진행하고 싶은데 다른 방법없을까요?
뀨
혹시 노트북이랑 pi랑 소켓 통신할때 둘의 연결이 유선으로 직접 연결되어있나요?
아니면 무선인가요?
어쨋든..
pi에서 저장한 이미지파일을 .jpg 형태의 단일 파일로 저장 한 뒤에 전송을 하는 것인가요?
아니면 pi에서 촬영하는 이미지를 실시간으로 pipe에 담아서 보내시나요?
만약, 단일 파일로 저장해서 전송하시는것이고...둘의 연결이 유선으로 직접 연결되어 있다면..
pi에서 전송한 뒤 노트북에 저장되는 폴더를
pi에서 nfs 폴더 공유 기능으로 잡아서 거기에 직접 저장하는 것은 어떠신가요?
pi에서 apt-get install nfs-kernel-server를 설치 한 뒤
노트북에서 저장할 폴더 가져와서 pi에 연동 시키면,
picam으로 저장한 이미즈를 그 연동시킨 폴더에 저장하게 되면
노트북에서 바로바로 실행해서 볼 수 있습니다.
자세한건 nfs폴더 공유 기능을 검색해서 참고해보세용
그냥 소켓을 두개 여세요...
하나는 이미지 전달용 하나는 명령 전달용
댓글 달기