python 소켓을 통한 이미지 전송 시 문제

cat90129의 이미지


안녕하세요, 파이카메라를 이용한 프로젝트 진행 중에 있는 학생입니다.

파이카메라와 소켓통신을 이용해서 작업을 진행하는데

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() 
           #를 해야 파일이 열린다. 하지만 소켓 연결이 끊어져서
           #연속적으로 다음 데이터를 받지를 못한다.

고수님들 부탁드립니다. ㅠ

peecky의 이미지

추정하건데, 클라이언트에서 파일의 마지막 부분을 보내면, 서버에서

image = connection.recv(buf) # 마지막 데이터를 받음
print "Receiving..."
if image:
print "1"
f.write(image) # 여기서 마지막 데이터를 write
image = connection.recv(buf) # 클라이언트가 sock.close()를 하지 않으면 여기서 무한 대기 상태에 빠짐

를 실행하고 계속 다음 패킷을 대기하는 중이라서 f.close()가 실행이 안 되고, 서버에서 이미지파일을 열어볼 수 없는 상태가 되는 것 같습니다.

해결은 다음처럼 하면 될 것 같습니다.
클라이언트에서 파일을 보낼 때, 파일 내용을 보내기 전에 몇 가지 정보(예를 들어 파일 크기)를 먼저 보냅니다.
서버에서는 파일 크기만큼 데이터를 받으면 f.close()를 실행하고 다음 파일을 받을 준비를 합니다.

cat90129의 이미지

감사합니다. 파일내용을 보내기 전에 파일크기를 보내려면 일단 capture 한 후 그 파일의 크기를 서버로 보내야하는데 그 크기를 추출하는 함수를 찾을 수가 없습니다. 방법을 알 수 있을까요?

cat90129의 이미지

감사합니다. 덕분에 파일사이즈 값을 서버로 보내서 그 만큼 버퍼로 만드는것까지 완성했습니다.

cat90129의 이미지

파일을 닫는 f.close()를 한후 파일이 아닌 그냥 데이터를 SERVER쪽에서 전송할 때도 위의 프로토콜을 구현하면 그냥 f.close()까지만 써도되는 건가요?

cat90129의 이미지

파일 사이즈 값을 서버로 보내서 서버에서 그 값만큼 버퍼를 만드는 것 까지 완성했는데요.
헌데 아직도 소켓을 닫기 전까지 파일이 열리질 않습니다.
끝나는 시점까지 알려줘서 어떤 문구를 보내고 그 문구가 왔을 시 f.close()를 하려하는데 어려움이 있습니다. 서버나 클라이언트나 f.close()로 파일전송을 완료 시키고 다음 데이터 전송을 계속 진행하고 싶은데 다른 방법없을까요?

skyjjogari의 이미지

혹시 노트북이랑 pi랑 소켓 통신할때 둘의 연결이 유선으로 직접 연결되어있나요?

아니면 무선인가요?

어쨋든..

pi에서 저장한 이미지파일을 .jpg 형태의 단일 파일로 저장 한 뒤에 전송을 하는 것인가요?

아니면 pi에서 촬영하는 이미지를 실시간으로 pipe에 담아서 보내시나요?

만약, 단일 파일로 저장해서 전송하시는것이고...둘의 연결이 유선으로 직접 연결되어 있다면..

pi에서 전송한 뒤 노트북에 저장되는 폴더를

pi에서 nfs 폴더 공유 기능으로 잡아서 거기에 직접 저장하는 것은 어떠신가요?

pi에서 apt-get install nfs-kernel-server를 설치 한 뒤

노트북에서 저장할 폴더 가져와서 pi에 연동 시키면,

picam으로 저장한 이미즈를 그 연동시킨 폴더에 저장하게 되면

노트북에서 바로바로 실행해서 볼 수 있습니다.

자세한건 nfs폴더 공유 기능을 검색해서 참고해보세용

xroot1의 이미지

하나는 이미지 전달용 하나는 명령 전달용

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.