• 締切済み

C言語でのネットワークプログラミング

現在Linuxを用いてC言語でTCP/IPのサーバ、クライアントプログラムを作成しています。 sendとrecvの正しい使い方がわかっておりません。 一度のrecvですべてのデータを受け取れないことはわかっているのですが、どのように記述するのが良いのでしょうか。1バイトずつrecvするのは大間違いであると何処かのサイトで読みました。 ・現在の仕様 サーバがデータの文字列をsendで送ってくる クライアントはrecvで1バイト読み込みを繰り返し、配列に格納し、\0を見つけるとループを抜ける recvした文字列を画面表示 表示したあとはrecvに戻る

みんなの回答

  • notnot
  • ベストアンサー率47% (4844/10254)
回答No.1

1バイトずつでも間違いとは言えないと思いますよ。普通はしないだけで。 100なり2000なり、サイズを指定して読み込んで、読み込めたバイト数だけコピーすれば良いかと。

関連するQ&A

  • ソケットプログラミング

    こんにちは。 ソケットプログラミングを勉強していて、音声を送りあえるIP電話らしきものを作ろうとしています。音声のやりとりは何とかできていますが、同時に文字列も送れるようにしたいです。ソケットをもう一つ作ればいいのではないかと思っていますが、実際に書いてみると、recv()の部分がうまく書けません。 音声データの送受信の部分は: while(1){ n=recv(sock,data1,N,0); //受信 if (n== -1){perror("recv");exit(1);} if(write(dsp, data1,n)==-1){perror("write"); exit(1);} //スピーカーから出力 n=read(dsp,data,N);  //マイクから入力 if (n== -1){perror("read");exit(1);} if(send(sock,data,n,0)==-1){perror("send");exit(1});} //送信 } 送信の時は n=read(0,tdata_2,N); send(sock_2,data_2,n,0); のように標準入力から文字列を読み込んで、data_2に格納し、新しく作ったソケットsock_2で送ればいいのですが、受信の時はどうしたらいいでしょうか。recv()をつかって、文字列と音声のデータを違うソケットで受け取って、違う配列に格納する方法があるでしょうか。 つまり、このような感じ(?): n1=recv(sock1,data1,N,0); //音声 n2=recv(sock2,data2,N,0); //文字列 とても悩んでますので、よろしくお願いします!!

  • C言語のプログラミングについてです。

    C言語のプログラミングについて教えて欲しいです。 scanf関数を用いて、キーボードから文字列(最大30文字)を読み込み、これをchar型配列に格納します。最大10個までの文字列が入力された場合か、「END」が入力された時、入力された逆順で画面に表示するプログラム。作成しなさい。 〈完成例〉 adjm 10mdjp jpd-4 njad' END njad jpd-4 10mdjp adjm

  • TCPのプログラミングで質問…というか確認しておきたいことが…

    このたびC言語でネットワークプログラミング(TCP)をしているのですが、気になったことがあったので、2点ほど質問させていただきます。 (1)WSock32のsendで一度に送信できる量は65535バイトと以前学んだのですが、受信側がrecvする前にどんどん65535バイト送信していったら受信側のソケットはどんどんいっぱいになってしまいますよね?その場合、限界はあるのでしょうか?また、一度にrecvできる量も65535バイトが限界なのでしょうか?もしそうだとしたら65535バイト以上データがあると取得しても残ってしまうんですか? (2)sendで大きなデータなどを送信した場合、受信側でrecvしたときに途中までのデータを受信してしまったりすることってありますか?たとえば、「"abcde"と送信したのに対し、受信側でrecvしたらとりあえず"abc"まで受信し、次のrecvで残りのデータを受信する」様なことってあるんでしょうか? すべてのデータがちゃんと送信されてからじゃないとrecvで取得することはできなくなっているんでしょうか… とてもとても分かりにくい文章で本当にすみません。 すべてとはいいません、少しでも情報があれば教えていただけませんでしょうか・・・ どうぞよろしくお願いいたしますm(_ _)m

  • C言語について教えてください。

    二次元配列でまとめられた「配列で実現する文字列」の文字と文字列を表示する関数を定義し、その関数の機能を確認するプログラムを作成する。 ただし、以下の例のように文字列の個数が変更されても処理できる関数を作成する。 また、文字列の文字の個数は最大9とする(一次元配列の要素数は10とする) さらに、関数printf()をできるだけ用いない。 (1)二次元配列でまとめられたすべての文字列を「一度に」表示する関数を定義する (2)二次元配列でまとめられたすべての文字列の文字を「一度に」表示する関数を定義する。このとき、前回の課題で定義した「すべての文字を表示する関数print_all_char()」を新しく定義する関数から呼び出して用いる。 (3)二次元配列に各文字列を格納してまとめるとき、初期化ではなく、配列の宣言・定義の後で、関数strcpy()を用いること(例では、初期化によりまとめている) [例] char astr[][10] = { "ABCD", "EFGHIJ", }; [実行結果の例] すべての文字列の表示 ABCD EFGHIJ すべての文字列の文字の表示 A B C D E F G H I J [ヒント] (1)二次元配列でまとめられた文字列の文字あるいは文字列を表示する関数<返却値型><関数名>(二次元配列の受け渡しに対応した仮引数の宣言、文字列の数) (2)文字列の数を求める。二次元配列のすべての要素に文字列が格納されている場合、文字列の数=二次元配列の要素数(一次元配列の数) =sizeof(astr)/sizeof(astr[0]) ただし、sizeof演算子の生成する型はsize_t型である。 この問題について教えてください。問題丸投げだとは分かっていますがどうしても分かりません。教えてください。ちなみに前回の課題の定義は下の通りです。 void print_all_char(char *chs) { while(*chs!='\0') { printf("%c\n",*chs); chs++; } } よろしくお願いします。

  • C++ TCP受信 突然切れる

    C++のTCPソケット(recv関数)を使ってサーバからデータを定期的に受信する クライアントを作っているんですが、データの受信中?に突然TCP接続が 切れることがあります。 より正確にはrecvの戻りが0(sizeが0=切断された)になってしまいます。 物理的に配線が切れたとかでもなく、誰も手を触れず放置した状態のときに突然 切れたりとかわけが分かりません。 もしかしてTCPソケットって接続し続けてはいけないとかあるんですかね? 分かる人がいたら宜しくお願いします。

  • 【C言語教えて下さい!】文字検索

    引数として、複数の文字列を格納した配列、その文字列数、あるいは文字列aを与え、aが複数の文字列を格納した配列中に見つかれば1を返し、見つからなければ0を返す関数find_string()をつくりたいのですがよくわかりません。 どなたかご教授お願いします。 ヒントや考え方など教えて下さい。

  • C言語を使用したプログラミング方法

    C言語をしようして、二次元配列に入ってるフォントデータを呼んで「@」と「O」で漢字一文字をコンソール画面に表示するプログラミングを教えていただけますか? 配列は[24][32]を使用します。 0のときは@で表示、1のときはOで表示 文字の例:木 24行、32列で文字を表現したいです。 @@@@@O@@@@@ @@@@@O@@@@@ @OOOOOOOOO@ @@@@OOO@@@@ @@@O@O@O@@@ @@O@@O@@O@@ @O@@@O@@@O@ O@@@@O@@@@O

  • コンマで区切られた、数値と文字列を含むファイルの入出力(C言語)

    C言語に関する質問があります。 数値と文字列を含む外部ファイルを読み込みたいのですが、方法が分かりません。もし良いアイディアを思いついた方、頭の良い方はぜひ回答よろしくお願いします。 外部ファイルは、以下のデータを1セットとして、この1セットのデータが改行されて、何千行もあるファイルです。 1セットのデータは41個の属性からなり、コンマで区切られています。 文字列のデータと、数値データ(連続値)からなります。 0,tcp,smtp,SF,829,327,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,8,113,0.88,0.25,0.12,0.02,0.00,0.00,0.00,0.00 ↓ 0,udp,private,SF,105,146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,255,253,0.99,0.01,0.00,0.00,0.00,0.00,0.00,0.00 ↓ . . . のように時系列データとなっています。 配列data[41]を用意し、41個のデータを data[0] = 0 data[1] = tcp data[2] = smtp data[3] = SF data[4] = 829 . . . のように配列に入れたいと考えています。 *配列に格納されているデータを計算で使うため、配列を使いたいと考え  ています。 上記の方法が可能か分かりませんが・・・ 当方まったくの初心者で困っています。よろしくお願いします。

  • C言語のプログラミングですが、

    C言語のプログラミングですが、 255文字以内の文字列をキーボードから入力して、下記の各処理を行うプログラム(※入力した文字データは配列に入力)はどのようにしたらいいでしょうか?(入力例:acFNkeexFFg) ・入力した文字列の最後の文字を出力 ・入力した文字列⇒逆に並べ替えて出力 ・入力した文字列⇒縦に出力(1文字ずつ) ・入力した文字列の中に「F」が何個あるか ただし、使えるのはfor文・配列・if文ぐらいでそれ以上レベルの高いものは使わないで下さい。 … char str[255]; int i,n,na,nb,nc; printf("Input Strings= "); scanf("%s",str); for(i=0;str[i]!='¥0';i++){ n=i; } printf("The last character= %c",str[n]); くらいまでしか分かりません…

  • TCP通信でrecvで不明な点。

    今、クライアントPCが接続してきて、接続できたら、そのクライアントが渡してくるデータを受け取るプログラムを作っています。下のプログラムを使用しています。 j = recv(NewSocket, RecvBuf, sizeof(RecvBuf), 0); ここで、データをRecvBufというのに入れて、そのデータ量が1212byteだというということがわかりました。それがだいたい5秒に1回程度受信されることがわかりました。 このプログラムだと1212byte受信後に、すぐに j = recv(NewSocket, RecvBuf, sizeof(RecvBuf), 0); このコードを実行しても j = 0が代入されていて、closesocket(NewSocket);が実施されて、接続を切断しているので、その接続を維持したままにできないかと思い、 if(j <= 0) // データを受け取ったか? break; // エラーなら抜ける この部分のプログラムをコメントアウトしてclosesocket(NewSocket);を実施しないようにしたら、5秒以上たっても、1212byteを受信できなくなってしまいました。 この方法だとなぜデータが受信できないのかご教授よろしくお願い致します。 (現在使用しているコードの一部) printf("%d番ポートで接続待機中\n", PORT); // 接続待機中のメッセージ表示 while(1) // サーバループ { i = sizeof(AddrInfo); // SOCKADDR構造体の長さをセットしておく NewSocket = accept(RootSocket, (SOCKADDR *)&AddrInfo, &i); // 接続を待ち受ける if(NewSocket == 0) // エラーがあるか? break; // エラーがあればサーバループを抜ける printf("%sと接続しました\n", inet_ntoa(AddrInfo.sin_addr)); // 接続元のIPアドレスを表示 // TCP/IPデータの受信 while(1) { j = recv(NewSocket, RecvBuf, sizeof(RecvBuf), 0); // クライアントからのデータを読み込む if(j <= 0) // データを受け取ったか? break; // エラーなら抜ける RecvBuf[j] = 0; // 受信データに文字列終端をセットする //if(strstr(RecvBuf, "q")) // qという文字列が含まれているか? // break; // そうならループを抜ける //for(i = 0; i < 30; i++) // 受信した文字列の長さだけ繰り返す // RecvBuf[i] += 1; // 1文字進める if(j != 0) // データを受け取ったか? { for(i = 0; i < 30; i++) // 受信した文字列の長さだけ繰り返す ShowBuf[i] = RecvBuf[i]; // 1文字進める //send(NewSocket, RecvBuf, strlen(RecvBuf), 0); // 加工したデータをクライアントに送信 for(i = 0; i < 30; i++) printf("%#x " , ShowBuf[i]); // サーバから受け取った文字列を表示 printf("cnt %d \n",j); } } //send(NewSocket, RecvBuf, strlen(RecvBuf), 0); // 加工したデータをクライアントに送信 closesocket(NewSocket); // 生成されたソケットを開放 printf("%sと切断しました\n", inet_ntoa(AddrInfo.sin_addr)); // 切断メッセージ表示 }