• 締切済み
  • すぐに回答を!

0byteデータの送信と受信

現在unixでsocketプログラムを書いています。 FTPライクなプログラムを書いているのですが、ファイルを送受信する場合、ファイルの終端をどうするかを考えています。 ファイルサイズを送るのはなしです。 sendで0byteのデータを送り、recvで0byteのデータを受信した場合にファイルの終端に達したとして処理を終らせたいと考えています。 実際、sendでは0byteのデータを送信してもエラーにはなりませんが、recvでは受信できません。 そのような処理はできるのでしょうか? よろしくおねがいします。

共感・応援の気持ちを伝えよう!

  • 回答数1
  • 閲覧数953
  • ありがとう数0

みんなの回答

  • 回答No.1
  • rinkun
  • ベストアンサー率44% (706/1571)

0byteのsendでは送信しているデータがないのだから受信側では何も受け取らない。recvはデータを受信するか接続が切られるかエラーになるかでないと返らないのでダメですね。送信側でcloseすればコネクションは切れるのでrecvは0で返るでしょう。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • バイナリデータ受信時のデータ順

    Winsockを用いてバイナリデータの送受信を行うプログラムを作成しました。 サイズは約4MBです。 データはすべて送受信できたようなのですが、バイナリエディタで確認したところ受信データがばらばらに入っているようなのです。完全にばらばらなのか、それとも塊ごとに後ろから順に入ってるのかまでは確認してません 受信方法としては BYTE buff; size_t fsize; recv( Recv, (char *)buff, sizeof(size_t), 0 ); memmove( &fsize, buff, sizeof(size_t) ); size_t Total = 0; BYTE *SubBuff = new BYTE[fsize*2]; BYTE *Buff = new BYTE[fsize]; while( Total < fsize ) { int n = recv(); memmove( &Buff[Total], SubBuff, n ); Total += n; } としています。 どのようにすれば、正しい受信ができるのかわかりません。教えていただけないでしょうか?

  • TCP/IP のパケットの分断と結合について

    linux で socket を使ってプログラムを作っております。 パケットの頭に、どんな種類のパケットかの情報を入れ、それに続く部分にデータを入れて送っております。受信側では、届いたパケットの頭の情報を見て必要な処理を行う、という流れになっております。 ところが、時々、次のような現象が発生して困っております。 ・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。 ・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。 これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか? それとも、linuxマシンの設定に問題があるのでしょうか?

  • C# ソケット通信でデータ受信時の欠損について

    Visualstudio 2013 を使用して C# で開発を行っています。 Socket Classを使用してデータの送受信をするプログラムを作成しているのですが、 非同期でデータを受信する際に取りこぼしなくデータを受信させる方法で悩んでいます。 現在行っているのは、  socket.BeginReceiveでデータ受信時のコールバック関数を登録し受信開始。  データ受信時のコールバック関数の中で  len = socket.EndReceive(ar);  byte[] rcvBuff = (byte[])ar.AsyncState;  でデータとサイズを取得  再度socket.BeginReceiveで受信開始。 としています。 悩んでいるのは EndReceive から、二回目のBeginReceiveまでの間に送られたデータを取りこぼしてしまうのではないかということです。 認識として間違っていたら指摘頂きたいです。 また、別の方法で非同期で取りこぼしなく受信できるやり方が有りましたらヒントでもよいので教えていただけたらと思います。 よろしくお願いします。

  • Winsockを用いてデータを交互に送信しあいたい

    チャットプログラムではないのですが、チャットプログラムのソースが参考になると思いネットで調べて見ましたが見つからなかったので質問させていただきます。 したいのは、.rarなどの圧縮されたファイル(サイズはGB単位)の送信(TCP)です。 トータルのファイルサイズとファイル名をBYTE配列に書き込む BYTE配列のサイズを送信後、BYTE配列を送信 (とりあえずここでトータルサイズを4MB(4×1024×1024)で割った商をQ、余りをRと置いておく) ファイルをバイナリ読み込みモードで開く 受け取ったという合図を受け取ったらファイルの先頭から4MB読み込んでBYTE配列に入れて送信 受け取ったという合図を受け取ったら続きから4MB読み込んでBYTE配列に入れて送信 ↑を先頭の分も合わせてQ回繰り返す。 受け取ったという合図を受け取ったら続きからRバイト読み込んでBYTE配列に入れて送信 ファイルを閉じる としたのですが、 ファイルの先頭から4MBは送信できているようなのですが、そこから先に進みません。 具体的には、4MBの受信したという合図を送っても、send関数が-1を返すようです プログラムは以下の通りです Server Winsockの設定やファイルのトータルサイズ云々なので略 listen( RecvSock, 5 ); fp = fopen( FileName, "rb" ); int TotalSend = 0; int i = -1; SendSock = accept(RecvSock, (struct sockaddr *)&Send, &len);//コメントアウトを外す場合はこれはコメントアウト while(1) { //SendSock = accept(RecvSock, (struct sockaddr *)&Send, &len); if( i == -1 ) { send( SendSock, (char *)&FileSize, 4, 0 ); //↓の配列サイズを入れたBYTE配列 send( SendSock, (char *)Buff, Size, 0 );//トータルファイルサイズとファイル名 delete []Buff;//BYTE *Buff = new BYTE[FileSize]としたため } //フラグ受信 { recv( SendSock, (char *)&i, 4, 0 ); } if( i == Q ) { fread( SendBuff, R, 1, fp ); while( TotalSend < R ) { TotalSend += send( SendSock, (char *)&SendBuff[TotalSend], R-TotalSend, 0 ); } } else if( i != -1 ) { fread( SendBuff, SendSize, 1, fp );// SendSizeは4*1024*1024の値を#define while( TotalSend < SendSize ) { TotalSend += send( SendSock, (char *)&SendBuff[TotalSend], SendSize-TotalSend, 0 ); } } printf( "%d/%d\n", i, Q ); } Client //Winsockの設定やファイルのトータルサイズ云々なので略 FILE *fp = fopen( FileName, "ab" ); int Total = 0; for( int i=0 ; i<=Q ; i++ ) { //connect( Sock, (struct sockaddr *)&Addr, sizeof(Addr) ); int Error = FileRecv( Sock, i, Q, R, fp ); if( Error == -1 ) { i--;//エラーが出るのでどこでエラーが出るのか見るために追加 } else { printf( "%d/%d\n", i, Q ); } } int FileRecv( SOCKET Sock, int Flag, int Q, int R, FILE *fp ) { //Winsockの設定をコメントアウト中。外した場合、引数のSOCKET Sockは消す int Total = 0; //フラグ送信 { BYTE buff[4]; memmove( buff, &Flag, 4 ); int Error = send( Sock, (char *)buff, 4, 0 ); if( Error == -1) { return -1; } } if( Flag == Q ){ Buff = new BYTE[R]; memset( Buff, 0, sizeof(Buff) ); while( Total < R ) { Total += recv( Sock, (char *)&Buff[Total], R-Total, 0 ); } fwrite( Buff, R, 1, fp ); delete []Buff; } else { Buff = new BYTE[SendSize]; memset( Buff, 0, sizeof(Buff) ); while( Total < SendSize ) { Total += recv( Sock, (char *)&Buff[Total], SendSize-Total, 0 ); if( Total == -1 ) { delete []Buff; return -1; } } fwrite( Buff, SendSize, 1, fp ); delete []Buff; } // closesocket(Sock); // WSACleanup(); return 1; } 毎回切断してもう一度接続しなおすようにしても(コメントアウトを外す)結果(エラー部)は変わりません。 どこが悪いのか見ていただけないでしょうか?

  • 計測用データを送信するには

    帯域測定プログラムを作っています。 まず送信側で通信に使用するデータサイズを決めて受信側に送信し、 そのデータを使って互いに送受信して帯域測定を行いたいです。 送信側で50000バイトのデータを使って計測を使用と決めて、50000バイトという情報を受信側に送信します。 int data = 50000; String unit = "byte"; byte[] send_size = (data+unit).getBytes(); out.write(send_size); out.flush(); これを受信側は受け取り50000バイトという数値に変換したいのですが、 変換の仕方が分かりません。 バイトに変換して送信しているので、5は53に、0は48に変換されているので、53->5、48->0というように変換してやりたいのですが、 どうすればよいのでしょうか? また、50000バイトという情報を相手側にもっと賢く遅れる方法があればそちらについてのアドバイスも頂きたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • sock.sendでTCP送信したデータ列の長さ

    現在、あるクライアント型のTCP端末でサーバーに対して送信するデータをwiresharkでキャプチャし、全く同じデータをraspberry pi3のpythonで送信できないかと思い、次のようなプログラムを作成しました。 testという配列に1212バイト分のデータを作成( print(len(test)))で1212byteを確認)し、sock.send(test)で送信したのですが、サーバーのアプリケーションにデータの受信を確認したという表示が出てこないため、ラズパイから送信されたTCPのパケットをwiresharkで確認したところ 1212byteで作成したはずのデータの長さが実際には1448byteとなっていることが分かりました。 パケット全体の大きさは通常の端末では1266byteのところ、ラズパイでは1514byteとなっていました。 1514 - 1266 = 248byte分は調べたところ配列testの 0x4d,0x45]) この後ろに0x00,0x00......が続いているようです。 このデータの長さを1212byteに変更することは可能かどうか教えていただきますよう、よろしくお願い致します。 (pythonのコード内容) from __future__ import print_function import socket import time import numpy as np from contextlib import closing def main(): host = '192.168.1.158' #host = '192.168.1.52' port = 5000 bufsize = 4096 loop= 0 testStr = "Hello world" test=np.array([0x88,0x88,0x88,0x53,0x00,0x01,0x00,0x00,0x88, 0x88,0x88,0x00,0x0c,0x04,0x13,0x89,0x01, 0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ---------------------(中略)------------------------------------------------------------------ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x4d,0x45]) print(len(test)) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) with closing(sock): sock.connect((host, port)) while 1: sock.send(test) #sock.send(b'20160001 Hello world'+ str(loop) + "\n") #sock.send(testStr) #sock.send(b'Hello world\n') time.sleep(10.0) loop += 1 #print(sock.recv(bufsize)) #return if __name__ == '__main__': main()

  • VB 8byte受信して6yte目選ぶ

    今現在,重量計で計った重さを,RS-232Cで受信するプログラムを作成中です。 8byteを受信しているのですが,6byte目の重量のデータしか必要がありません。6yte目のみ取り出せるのですか? 宜しく御願いします。

  • TCP/IP通信プログラミングにおけるデータ送信タイミングと受信データ処理のタイミングについて

    現在Winsockを用いてTCP/IPメッセージ通信を行うプログラムを作成 しています。 メッセージはヌル文字区切りで送信され、ヌルが発見されると一つの メッセージの終わりということにしてあります。 このメッセージを時間ウェイトを入れずに連続して送信すると受信側で 正常にデータが受信できず、送信したデータの一部しか受信できません。 ある程度の時間ウェイトを入れてやることで正常に送受信できるように なります。 受信側の処理において、recvでデータを取得した後にメッセージパーズ 処理を入れているのですがそれほど重い処理でもありません。いろいろ 調べたのですが正常に送受信するときとしないときの違いが連続送信時 に入れる時間ウェイトにあるということしかわかっておりません。 これがTCP/IPの特性なのか私の開発環境(PC・ネットワーク)に起因する ものなのかがわかりません。どなたかこういった現象についてご経験を お持ちの方がおられましたらご教授願いたいと思っております。 以上

  • recv 受信

    送信データが 1500BYTE以上の場合、recvで完全な受信ができない場合、どんな対策が御座いますか?教えて下さい. 因みに、recvは以下のように実行しています. recv(sock, bBuf, size, 0);

  • Winsockを利用した単純なファイル送信プログラムについて

    こんばんは。 何度もこの掲示板を利用させていただいている者です。 WinsockのUDPを用いて簡単なファイル送信プログラムを作っています。UDPを使わずに、TCPを使用したほうが良いのでは?とのご指摘をいただきましたが、まずは、UDPを利用した単純なファイル送信プログラムを作ってみたいと思っています。 しかし、送信側から受信側へファイルがうまく受信できていません。もしかしたら、送信側自体がきちんと送信できていないのかもしれません。 以下にそのプログラムの概要と内容を示します。 [概要] 送信側→受信側にUDPを用いて、送信側にあるjpegまたはmpegファイルを送信し、受信側でファイルを開く。 [プログラム概要] ・送信側 ファイルポインタを用いてファイルオープン fread関数とsendto関数を用いて1024バイトずつ送信 ・受信側 ファイルポインタを用いてファイルオープン whileの無限ループ内に、recvfrom関数とfwrite関数を用いて送信側からのデータを受信 [プログラムの内容] ・送信側 printf("読み込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"rb")) == NULL){ printf("入力ファイルをオープンできない。\n"); exit(1); } char send_buf[1025]; int n; while(n = fread(send_buf,1,1024,fp) != -1){ sendto(theSocket,send_buf,n,0,(LPSOCKADDR)&saServer,sizeof(struct sockaddr)); } ・受信側 char Recv_buf[1025]; char size; SOCKADDR_IN saClient; while(1){ size = recvfrom(theSocket,Recv_buf,1024,0,(LPSOCKADDR)&saClient,&nLen); fwrite(Recv_buf,size,1,fp); } ご指摘またはご教授をいただけたらと思います。 よろしくお願いします。