• 締切済み

recvfrom関数の戻り値がおかしいんですが…

Vidocqの回答

  • Vidocq
  • ベストアンサー率66% (6/9)
回答No.1

4バイトのみ、というのが気になります。 考えにくいのですが、sizeof buf となっているところを 4096 に変えてみて試してはいかがでしょうか。

noname#107905
質問者

お礼

Vidocqさん、早速の回答ありがとうございます。 回答いただいたとおりに、’sizeof buf’部分を’4096’に変更し、 再度デバックしたところ、期待通りのデータをbuf変数に格納することができました。 ただ、なぜ具体的な数値を指定しただけで、きちんと格納できたのかが、 全く理解できません。 main関数内での実行とユーザ関数内での実行との違いとすれば、 bufポインタ変数の宣言を、main関数ではローカル宣言、ユーザ関数ではグローバル宣言しているぐらいなものです。 ユーザ関数定義ソース内では、ユーザ関数1と2とあり、各関数で同一の変数名を使用したいと思い、グローバル宣言にしています。 グローバル宣言とローカル宣言で何か違いでもあるのでしょうか。 ちなみに、デバッカでmain関数内でのコール時とユーザ関数内でのコール時で、recvfrom関数コール直前の’buf’変数内部の格納データを比べてみたところ、以下のような明らかな違いがありました。 ◆main関数内コール buf = '\000' <repeats 2500 times>"\236, \037\211", '\000' <repeats 25 times>"\370, \371\377\26 ... ◆ユーザ関数内コール buf = 0x804d200 "" sizeof bufを4096に変更した場合でも、ユーザ関数内コール時のbuf変数格納値はrecvfrom関数コールするまでは同じでした。 何か具体的な原因をつかみたいものですが、思い当たるところございませんでしょうか?

関連するQ&A

  • recv関数でフリーズしてしまう

    現在Winsockを用いた簡単なパケット送受信のソフトを作成しています。 開発環境はVisual Studio2008で、ダイアログベースで作成しています。 パケットの受信側の処理なんですが、いつパケットが来てもいいように、 Ontimerで、定期的に受信処理をしようと思っています。 そこでOntimer内に以下のようにプログラムしたところ、コンパイルエラー はないものの、数秒経つと応答なしとなりフリーズしてしまいます。 原因を探ったところrecv関数が原因で、recv関数をコメントアウトした ところ、フリーズはしなくなりました。また、エラー処理は省略していま すが、ソケットの作成失敗などはありませんでした。 なぜrecv関数でフリーズが起きてしまうのか、原因が分かる方は いらっしゃいますか? OnTimer(UINT nIDEvent){ WSAData wsaData; SOCKET sock; struct sockaddr_in addr; char buf[2048]; WSAStartup(MAKEWORD(2,0), &wsaData); sock = socket(AF_INET, SOCK_DGRAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(12345); addr.sin_addr.S_un.S_addr = INADDR_ANY; bind(sock, (struct sockaddr *)&addr, sizeof(addr)); memset(buf, 0, sizeof(buf)); recv(sock, buf, sizeof(buf), 0); closesocket(sock); WSACleanup(); }

  • UDP通信について

    UDP通信で困っています。 TCP/IP通信はすぐにうまくいったのですが、 UDPの簡単なサンプルがちゃんと動きません。 間違いがあればご指摘ください。 よろしくお願いします。 (クライアント側ソース int sock; struct sockaddr_in din; memset(&din, 0, sizeof(din)); din.sin_port = htons(50050); din.sin_family = AF_INET; din.sin_addr.s_addr = inet_addr("サーバーIP"); sock = socket(AF_INET, SOCK_DGRAM, 0); int buf = 12345; sendto(sock,(char*)&buf,sizeof(int),0,(struct sockaddr*)&din,sizeof(struct sockaddr_in)); (サーバー側ソース int sock; struct sockaddr_in sin; sock = socket(AF_INET, SOCK_DGRAM, 0); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(50050); sin.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { return(1); } struct sockaddr_in fromaddr; socklen_t len = sizeof(struct sockaddr_in); int buf; recvfrom(sock,(char*)&buf,sizeof(int),0,(struct sockaddr*)&fromaddr,&len); printf("recv:%d\n",buf);

  • 中身が同じような関数を一つの関数にしたい

    void C_Commu::Recv( vector<void *> Data ) { ----BYTE *Buf; ----int TotalSize, RecvSize; --------TotalSize = Data.size()*sizeof(Data[0]); --------Buf = new BYTE[TotalSize]; --------while( RecvSize < TotalSize ) --------{ ------------RecvSize += recv( Sock, (char *)Buf, TotalSize-RecvSize, 0 ); --------} --------memcpy( &Data[0], Buf, TotalSize ); } このような関数を作ってみたのですが、 C_Commu::Recv( Data->CharaNum ); //vector<char> CharaNum C_Commu::Recv( Data->Model ); //vector<S_Model> Model(S_Modelは構造体) としてみると 'C_Commu::Recv' : 1 番目の引数を 'std::vector<_Ty>' から 'std::vector<_Ty>' に変換できません。 とエラーになります。 使いたい動的配列が違うだけで残りは同じ関数なので一つに纏めてみたのですがどうしてエラーになるのか分かりません。 どのようにしたらいいのでしょうか?

  • MacOSXでのネットワークプログラミング

    MacOSXでのネットワークプログラミング 現在、MacOSXでC言語を使用してネットワークプログラミングを勉強しています。 簡単なクライアントアプリケーションを作成して、サーバーに接続しようとするのですが、 connect関数のところで、エラーが発生して失敗してしまいます。 エラー関数を調べたところ、errno=13, 「Permission denied」がでています。 root権限で実行、ファイアウォールを無効にしても同じでした。 原因が分からないので、よろしくお願いします。 ◯サンプルソース int main() { struct sockaddr_in server; int sock, n; char buf[32]; sock = socket(AF_INET, SOCK_STREAM, 0); server.sin_family = AF_INET; server.sin_port = htons(80); server.sin_addr.s_addr = inet_addr("www.google.co.jp"); n = connect(sock, (struct sockaddr *) &server, sizeof (server)); if (n == -1) { printf("[ERROR](%d): %s\n", errno, strerror(errno)); } else { memset(buf, 0, sizeof (buf)); n = read(sock, buf, sizeof (buf)); printf("%d, %s\n", n, buf); } close(sock); return 0; } ◯開発環境 MacOSX 10.6 (64bit) Netbeans 6.8 gcc 4.2.1

  • 外部シンボルって

    本に載っていた以下のようなサンプルコード #include <stdio.h> #include <winsock.h> void main( void ) { WSADATA wsadata; if ( WSAStartup( 0x0101, &wsadata ) != 0 ) { printf( "WSAStartup の実行に失敗 %d\n", WSAGetLastError()); } int sock; struct sockaddr_in addr; int ret ; struct hostent *hostinfo; unsigned long inetaddress; char *hostname = "localhost"; inetaddress = inet_addr( hostname ); if ( inetaddress == INADDR_NONE ) { hostinfo = gethostbyname( hostname ); if ( hostinfo == 0 ) { // ホスト名解決に失敗 return ; } inetaddress = *(unsigned long *)hostinfo->h_addr_list[0]; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inetaddress; addr.sin_port = htons(80); sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); ret = connect( sock, (struct sockaddr *)&addr, sizeof addr ); if ( ret < 0 ) { printf( "localhost 80 に接続できなかった" ); return ; } char get[] = "GET /index.html HTTP/1.0\r\n\r\n"; send( sock, get, strlen(get), 0 ); char buf[256]; int n; printf( "recv data\n" ); while ( 1 ) { n = recv( sock, buf, sizeof(buf)-1, 0 ); if ( n <= 0 ) break; buf[ n ] = '\0'; printf( buf ); } closesocket( sock ); WSACleanup(); } をVC++6.0でコンパイルしたのですが sample_client_win.obj : error LNK2001: 外部シンボル "_WSACleanup@0" は未解決です のようなコンパイルエラーが出て実行できません。これはなにが悪いのでしょうか。本に載っているサンプルコードなのでソース自体は間違っていないと思うのですが・・・もしよろしかったらご教授ください。

  • 関数の型

    C言語の勉強をしております。 以下のように、入力用の関数を作成し、入力された文字列を返して欲しいんですが、「1 番目の引数を 'char *[80]' から 'char *' に変換できません。」という警告メッセージが出てしまい、解決出来ません・・・。 原因と解決策を教えていただけないでしょうか? ちなみに環境はWindowsXP、コンパイラはVC6.0です。 #include <stdio.h> char *insertName(char *buf); int main(void) { char *buf[80]; buf = insertName(buf); printf(buf); return 1; } char *insertName(char *buf) { gets(buf); return buf; } mainの「buf」の定義を「char *buf」にすればエラーは出ないんですが、大きさを指定したいので・・・ どうかよろしくお願いいたします。

  • 関数のパラメーターと戻り値について

    VB.NET 関数の定義とパラメータの設定と戻り値について質問です。 初心者です。 以下のような戻り値が複数ある関数を定義したいのですが、IN,OUTがよくわからなくて、困っています。DB検索となにか関係があるのでしょうか? 関数名: Fnc パラメータ:Enpno(Char) /IN パラメータ:EnpCD(Char) /OUT パラメータ:EnpNM(Varchar) /OUT 初期値:Enpno = S123 処理内容:DB接続して、Enpnoが一致する場合、戻り値としてEnpCDとEnpNMを返す。DB検索でしようするは,Enpnoのみ。 ByLefで戻り値を2つ返すというようなコードを見たのですが、OUTのときに使えばよいということなのでようか?とどなたか教えてください。 よろしくお願いします。

  • 配列とポインタについて

    こんばんわ。 WinSockを利用してネットワークプログラミングを行っています。 以下のようなプログラムを作成したのですが、実行できません。 以下のプログラムは質問箇所を抜き出したものです。 [プログラム] int Receive(u_short portNo) { char recv_Buf[1025],recv_Buff[1025]; size = recvfrom(s2, recv_Buf, (int)sizeof(recv_Buf) - 1, 0, (SOCKADDR *)&from, &fromlen); recv_Buff = recv_Buf; Sender(portNo,szServer,recv_Buff); } int Send(unsigned short portNo,char *szServer,char *recv_Buff) { sendto(s1, recv_Buff, (int)strlen(recv_Buff), 0, (LPSOCKADDR)&addrin1, sizeof(addrin1)); } このプログラムは、Receive関数内のrecvfrom関数で1024Byte(recv_Buf[1025])受信したデータをSend関数内のsendto関数で送信するというプログラムです。 recv_Buf = recv_Buffにてエラーが発生します。なにか解決策はりますでしょうか? また、Receive関数およびSend関数は何回も呼ばれるのですが、配列は初期化する必要があるのでしょうか? よろしくお願いします。

  • TCPでの非同期型select関数について

    マッキントッシュOS-X上で動くTCP通信プログラムを作る場合について教えてください。 ウィンドウアプリを考えています。 ウィンドウ環境なので、アプリがフリーズしてしまわないために、 以下のような非同期処理が考えられます。 この場合、データが来ていなくても、while(1)がぐるぐる回るので 無駄にプロセスを食ってしまうと思うのですが、これはしかたのないことでしょうか。 もっとよい方法がるのでしょうか。 Winsockだとイベント応答関数での受信処理処理ができてエレガントなのですが、 バークレイソケットでは、どうすべきなのか疑問に思い質問させていただきました。 よろしくお願いします。 //ソケットを非同期モードにセット val = 1; ioctl(sock, FIONBIO, &val); while (1) {   memcpy(&fds, &readfds, sizeof(fd_set));   select(2, &fds, NULL, NULL, NULL);   // sockに読み込み可能データが届いている場合は、受信   if (FD_ISSET(sock, &fds)) {     memset(buf, 0, sizeof(buf));     recv(sock, buf, sizeof(buf), 0);   }   else{     //受信データがなかったときの処理   } }

  • プログラミング(関数reverseを作る)

    プログラミングの勉強会で文字列を反転させる関数(例:ABCDE→EDCBA)を作れという課題が出たのですが、以下のように書いたきり進みません。あと、何を書けばいいのでしょうか?教えてください。 #include <stdio.h> void reverse(char *); void reverse2(char *); void main(){ char buf[10]; printf("str :"); fgets(buf, 10, stdin); reverse(buf); printf("rev :%s", buf); return; } //文字列を反転させる関数 void reverse(char *s){ return; }