VisualC++6.0(SDK)を用いてSocket通信(UDP)プログラムを
作成(チャットやメッセンジャーのようなもの)しています。

送信用と受信用
1つのプログラムにて、送受信両方の機能を兼ね備えたものを作成しようと思っています。

で、送信側から送ったデータを受信側で処理(文字列の追加など)をして
受信側から送信側に送り戻したいとおもいます。
送信ボタンにより送信します。受信したデータはエディットボックスに表示します。

が、受信したデータを送り返すとしているために、
いつまでも、受信->送信->受信・・・・を繰り返してしまいます。

これを、正しく動作するようにするには、どのようにしたら良いのでしょうか?
ご存知の方宜しくお願い致します。
足りないものがあったら、補足させていただきます。

このQ&Aに関連する最新のQ&A

A 回答 (9件)

>ラッピング??


>似たような処理で覆い隠す?ということでしょうか。

大体そのような感じです。今回は「送信バッファへの操作を構造体への操作に置換できる」ような送信処理関数を考えています。

下半分の解説ですが,まず,前回のpacket_send()を2箇所訂正させてください。
BOOL packet_send(struct packet *p){
char buf[BUFSIZE];
#define p_type(p) ((u_char *)(p))
#define p_data(p) ( ((char *)p)+1 ) //訂正:型変換がまずかった。

*p_type(buf)=(u_char)p->type; //訂正:ポインタ参照の * が抜けていた。
strncpy(p_data(buf),p->data,DATASIZE);
sendto(..., buf, BUFSIZE, ...);
...
}

このpacket_send()の動作は
1.構造体の内容を送信バッファへとコピーする。
2.作成した送信バッファをsendto()で送信する。
が目的です。(エラー処理は行っていない)

その上で,質問のこの2文ですが,
#define p_type(p) ((u_char *)(p))
#define p_data(p) ( ((char *)p)+1 ) //訂正:型変換がまずかった。
これは,送受信バッファ中で type, data, それぞれの位置(ポインタ)を取得するためのマクロです。目的は,送信/受信時にバッファの処理を共通化すること,後にプロトコルの改変を容易にすること,の2つ。関数に置き換えると

//バッファ中のtypeを示すポインタを取得
u_char *p_type(void *p){ return (u_char *)(p);}
//バッファ中のdataを示すポインタを取得
char *p_data(void *p){ return ( ((char *)p)+1 );}

のようになります。
## 引数にpじゃなく,bufを使ったほうがよかったかな?
    • good
    • 0
この回答へのお礼

大変よく分かりました。
ポインタを取得していたんですか。

ありがとうございました。


少々話は変わるのですが、
ターゲットを見つける(接続が確立されている確認)というのも、
今までのように、返信データを用いて戻ってきたら、接続が確立されている
という処理しかないのでしょうか?
繋がっている、繋がっていないということが、わかる方法はないのでしょうか?

ご存知でしたら、教えていただけませんでしょうか。

お礼日時:2002/04/15 17:01

UDPだとそうなりますね。

パケットタイプのフィールドを活用すると,いい感じにUDP pingを実装できそう。
    • good
    • 0
この回答へのお礼

遅くなりましたが、
なんとか、なりました。

大変ありがとう御座いました。
また、質問したときは、よろしくお願いします。

お礼日時:2002/05/07 16:19

UDP自体が接続(セッション)を確立しない通信ですから,無理です。


必要ならTCPを使いましょう。TCPなら,エラー処理でそういった状態を捕まえられます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
質問がどんどん、逆行しているようで申し訳ないです。

ということは、
試しと言うかで、1回送って返信作業をやって、
戻ってきたら、繋がっているということがある意味
接続確立テストということですね。

お礼日時:2002/04/16 10:04

> 確か、「構造体の中を連続した領域で確保せよ!」という命令の仕方があった気がするのですが、



packed構造体ですね。
これは,C,C++言語で規定されていないので,それぞれのコンパイラに依存したコードが必要になります。

など偉そうなことをいいながら,私もVC++でのpacked構造体の使い方覚えていません。(^^;; VC++のヘルプを覗いてみてください。

私ならpacked構造体を使わず,このように送信処理をラッピングしてしますね。

#define BUFSIZE 100
#define DATASIZE (BUFSIZE-1)

typedef enum packet_type{
PACKET_SEND=0x01,
PACKET_ACK=0x02
} ptype_t;

struct packet{
ptype_t type;
char data[DATASIZE];
}

BOOL packet_send(struct packet *p){
char buf[BUFSIZE];
#define p_type(p) ((u_char *)(p))
#define p_data(p) ((u_char *)(p+1))

p_type(buf)=(u_char)p->type;
strncpy(p_data(buf),p->data,DATASIZE);
sendto(..., buf, BUFSIZE, ...);
...
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
packet構造体、調べてみようと思います。

ラッピング??
似たような処理で覆い隠す?ということでしょうか。見た感じだと。

BOOL packet_send(struct packet *p){
char buf[BUFSIZE];
#define p_type(p) ((u_char *)(p))
#define p_data(p) ((u_char *)(p+1))

p_type(buf)=(u_char)p->type;
strncpy(p_data(buf),p->data,DATASIZE);
sendto(..., buf, BUFSIZE, ...);
...
}

上半分は分かったのですが(単なる定義なので)、
下半分がいまいち理解できません。
特に
#define p_type(p) ((u_char *)(p))
#define p_data(p) ((u_char *)(p+1))
の部分など。
もし宜しかったから、解説してはいただけないでしょうか?

お礼日時:2002/04/05 10:18

 こんにちは、honiyonです。



  struct THoge {
   char A[2]; //0~2の計3byte
   char B[2]; //0~2の計3byte
  }

 と、THoge構造体を定義すると、メモリ上では、

   AAABBB

 と連続した 6byteの領域が確保される・・・と思いがちですが、実はそうではないのです。 THoge構造体のなかの、A, B各変数は全く別の場所に確保される事があります。

 つまり、 THoge hoge; と宣言して、 @hoge として sendしても、中身を正常に送信出来ないという事になります。

 確か、「構造体の中を連続した領域で確保せよ!」という命令の仕方があった気がするのですが、C/C++ではどうやってやるか忘れてしまいました(^^; 識者の方からの補足お待ちします(笑 お願いします(..

 では、それ以外の方法での解決策としては、構造体の中身を手動で連続した領域に転送してやる事です。
 例えば、
 char Data[6]; //0~6 6byte.
 と宣言して、

 strcpy(@Data[0], hoge.A);
strcpy(@Data[3], hoge.B);

 とすれば、Dataの中には、 AAABBB\0 が入りますので、Dataの中の 0~5をsendすればOKです。 構造体の中に文字列以外が含まれる場合は、strcpyではなくmemcpyを使えば良いです。

 今回のケースにおいては、構造体の内容は、送受信フラグとメッセージのみのようなので、↑のような面倒な事をするよりは、今行われている通り、「メッセージ中の最初の1byteをフラグに使用」という方がシンプルで良いかも知れません(笑

 あまり良い回答ではないですが、参考になれば幸いです(.. 
    • good
    • 0
この回答へのお礼

>構造体の中を連続した領域で確保せよ!

やっぱりそういうのがあるんですね。
補足お待ちしております。
使いこなせるかどうかは別ですが・・・(^^j

構造体は連続した値ではないので、
手動にて、連続したデータを自分で作ってしまう。ナルホド。〆(。。)

やっぱり、中身は手動でも、データ定義のときに
構造体だとかっこいいですよね。

大変参考になりました。
ありがとうございました。

お礼日時:2002/04/04 15:36

こんにちは、honiyonです。



 送受信部についての具体例です。
 送受信パケットは、Packet構造体に収められているとします。
 「~ xxxx ~」は処理の省略です。

/*** 送信ボタンを押された時の処理 ***/
 void OnSendButtonClick(){
  ////// パケット作成処理
  Packet.DataType = true; //初送信を示す。
  ~その他メッセージ等をPacketに詰め込む処理~

  ////// データ送信処理
  ~パケットを相手に送信する~
 }

 /*** 受信を受けた時の処理 ***/
 void OnRecvData(){
  ~受信処理を行う~
  ////// 初送信データなら返信する
  if (Packet.DataType){
   Packet.DataType = false; //not 初送信として循環防止!
   ~返信処理~

  ////// 返信されてきたデータならチェック
  } else {
   ~チェック処理~
  }
 }

 こんな感じになると思います。
 参考になれば幸いです(..
    • good
    • 0
この回答へのお礼

honiyonさん、回答いただきありがとうございます。

バッチリ b(^^)d 動作できました。

でも、一つだけ分からないことがあったために、
もう一つだけ甘えさせてもらってもよいでしょうか?

Packet構造体にデータとフラグを詰め込んだとしますよね。
struct Packet{
  bool Type;
  char Data[1000];
}

とした場合に、送信時のsendtoにてキャストが出来ません。
sendtoの第2引数です。

で、今回は無理やりに文字列の1番目に力技にてフラグを入れたのですが、
構造体の方がスマートなやり方だと思っても出来ませんでした。

大変申し訳ありませんが、よろしくお願いできませんでしょうか?

お礼日時:2002/04/02 15:41

こんにちは、honiyonです。



 そのような仕組みでしたら、送信データに「送信データか。返信データか」を見分けるチェック用フラグをもつ事で対応出来ると思います。
 例えば、チェック用フラグを、送信ボタンで送信したデータはtrue, 返信するデータはfalseに設定し、受信側は、trueのデータであれば返信、falseならそのまま。とします。

 既にこの仕組みは実践されているようですが、うまくいかないのであれば、それはバグであると思われます。再度コードをチェックしてみましょう。

 因みに、データの整合性をチェックする場合、データを返送するという方法ではうまくいかないと思います。返信時にデータが壊れる可能性も考えられるからです。(UDPで壊れる可能性ってあまりないですけどね^^;)
 データをチェックしたい場合は、一般に「パリティチェック」と呼ばれる手法が使われます。

 簡単に言えば、データを2進数に直し、1の数を数えます。(0でもOK)その合計が、奇数であった場合は、1ビット足して、偶数にします。(その逆でもOK)
 そして受信側で、同じように1の数を数え、必ず偶数になるようにそろえているのに、奇数になっていたら、どこかデータが壊れている!と判断できます。
 壊れていたら再送を要求するなり何なりで対応します。

 詳しく以下のサイトにのっているので参考にしてみてください。
http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text …
 ちょっと目的が違うページですが、軽く検索してみたところ、これが一番詳細に説明していましたので(^^;

 参考になれば幸いです(..

この回答への補足

考え方としては合っているんですね。
TRUEとFALSEの判断が上手くいっていないんで、
何かが違うのかなと思っていたのですが、流れの問題ですか。
流れ図的なものを書いても、コッチが送信で、こっちは受信
受信で送信?と書いているうちに今、どっちの処理をやっていたんだ?
と分らなくなってしまって、ぐちゃぐちゃになってしまって分らなくなっていました。

もし良かったら、送信と受信の判断部の処理を簡単にでも良いので、
説明しては戴けませんでしょうか?

補足日時:2002/03/31 06:46
    • good
    • 0

デバッガを使う,printf()デバッグを行う,などしてプログラム内部での処理の流れを確認してみては?

この回答への補足

デバッカは当然使っていますし、
TRACE0なども用いています。
そのほかの使い方ということでしょうか?
詳細にお願いできませんか?
どこの流れを確認したら良いのでしょうか?

補足日時:2002/03/31 06:38
    • good
    • 0

こんにちは、honiyonです。



 本来ならば、どのような動作にしたいのでしょうか?

 メッセンジャーのようなもの(1対1での会話)にしたいのであれば、受信したデータは返信せずに画面に表示して終わりにすれば良いかと思います。

この回答への補足

早速、ありがとうございます。

>本来ならば、どのような動作にしたいのでしょうか?
>メッセンジャーのようなもの(1対1での会話)にしたいのであれば、受信したデータは返信せずに画面に表示して終わりにすれば良
>いかと思います。
送信側から、送信ボタンを押すことによって、何度でも送信が行えるようにしたいのです。
通信チェックプログラムのようなものともいえますが、
送ったデータを受信側で持っているデータと比較して正しいか誤っているかを判断したいんです。

私が、やってみたのは、送信データにフラグのようなものを付加して(送信側はONとか)
送信側なら、受信側から送ってきた物に返事は出さない。
というようにしたのですが、一度送信したら2度目は送り返さなくなってしまいました。
受信スレッド:recvfrom -> sendto
送信ボタン・イベント:sendto
です。

よろしくお願いします。

補足日時:2002/03/29 17:52
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qselect(ソケット)

ソケットを用いてプログラミングしていると、よく出てくると思うのですが、次の意味を教えてください。
select(SH); $| = 1; select(STDOUT);
$|(特殊記号)やSTDOUTなど、なるべる細かく教えて頂けると幸いです。
よろしくお願いします。

Aベストアンサー

ソケットは効率的な処理をするために通常はバッファリングするモードになっています。
(その都度処理するよりある程度やりとりするデータが溜まってまとめてやったほうが効率的)

これを回避(フラッシュ)したいときにselect(SH)のように
ソケットを選んで$|=1 でフラッシュモードに切り替えています。
詳しくないのですがプログラミングにおいてフラッシュが用いられるのは、ソケット通信で双方向にやり取りするときが多いと思います。
ちなみにソケットをclose(SH)すると自動的にフラッシュしてくれます。

また、デフォルトではSTDOUTが選択状態になっていますので
> print "hello.\n";

> print STDOUT "hello.\n";
の省略形というわけです。

余談ですが、Perl使いは面倒くさがりが多いので慣用句みたいに
> select((select(SH),$|=1)[0]);
と、まとめて書く人もいます。
これはselectが返す値が直前まで選択されていたソケットだからできる技です。

ソケットは効率的な処理をするために通常はバッファリングするモードになっています。
(その都度処理するよりある程度やりとりするデータが溜まってまとめてやったほうが効率的)

これを回避(フラッシュ)したいときにselect(SH)のように
ソケットを選んで$|=1 でフラッシュモードに切り替えています。
詳しくないのですがプログラミングにおいてフラッシュが用いられるのは、ソケット通信で双方向にやり取りするときが多いと思います。
ちなみにソケットをclose(SH)すると自動的にフラッシュしてくれま...続きを読む

QCプログラム UDP送信の送信データに関して

以下の2つのプログラムでの質問なのですが、

#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int main()
{
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in addr;

WSAStartup(MAKEWORD(2, 0), &wsaData);
sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(3054);
addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.3 ");

sendto(sock, "\x42\42\0\0\0\0\2\0\1\2\x44\x33\5", 13, 0, (struct sockaddr *)&addr, sizeof(addr));

closesocket(sock);
WSACleanup();

return 0;
}





#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int main()
{
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in addr;

WSAStartup(MAKEWORD(2, 0), &wsaData);
sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(3054);
addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.3 ");

sendto(sock, "HELLO", 5, 0, (struct sockaddr *)&addr, sizeof(addr));

closesocket(sock);
WSACleanup();

return 0;
}

について、送信データ部分に「¥」入ることによって、送信プロセスでどのような処理がなされているのですか?
¥~¥までで1バイトということで処理してくださいね、と処理系?に指示しているのですか?

また、「¥」はC言語ならではの表記の仕方なのですか?少し、伝えるのが難しいですが、何でもいいのでご回答頂けませんか?宜しくお願いします。

以下の2つのプログラムでの質問なのですが、

#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int main()
{
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in addr;

WSAStartup(MAKEWORD(2, 0), &wsaData);
sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(3054);
addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.3 ");

sendto(sock, "\x42\42\0\0\0\0\2\0\1\2\x44\x33\5", 13, 0, (struct sockaddr *)&addr, sizeof(addr));

close...続きを読む

Aベストアンサー

ただの文字定数の8進表記と16進表記です。
http://msdn.microsoft.com/ja-jp/library/edsza5ck.aspx

QTCP/IPプログラミングでのselectについて

selectは使用しているソケットのディスクリプタを登録させれば、send、writeシステムコールからのデータの受信等は検知しますよね。
では、コネクション要求(connect)は、検知するのでしょうか?
どなたか回答よろしくお願いします。

Aベストアンサー

もちろん検知しますよ。
LISTENしているソケットに対しての要求を検知したら
acceptしてやればOKです。

QUDPの送信確認

こんにちは。

現在、UDP通信でネットワーク上の別PCからデータ受信をしているのですが、偶に相手からデータが送られてきた後、こちらからACKを返さない時があります。

UDP通信なので相手にきちんとACKが届いたかの確認は出来ないかと思うのですが、こちらがACKを送ったかどうか確認出来るような関数?API?はないのでしょうか?

もしあるようでしたらご教授お願いします。

Aベストアンサー

結論から申し上げますと「ありません」

「ACK」と呼んでいますが、UDPから見ればユーザデータの一つに過ぎません。
ですので、ご質問にある「ACKを送ったかどうかを確認する」というのは「あるユーザデータを送ったかどうかを確認する」というのと同じことになります。

しかも、UDPに限らずどのレイヤのプロトコルでもそうですが、通常上位レイヤのデータについて解析する術を持っていません。

つまり、そのユーザデータが「ACK」であることをUDP以下の各レイヤにわからせることはできないことになります。

パケットは常に失われる可能性を持っています。
信頼性を重視したいのであれば、No1 ___noboru___さんの回答にもあるように TCP の使用もご検討されるべきだと思います。

こんな感じでいかがでしょうか。

Qselectの意味

selectの意味

リファレンスマニュアルと本のselectの説明がわかりません。
説明の文はなんとかわかるのですが、引数のとり方が「reads[, writes[, excepts[, timeout]]]」となっていて、これは 3 要素の配列を返しているように見えないので、混乱します。「reads[, writes[], excepts[], timeout[]」という書き方なら3 要素の配列を返していると納得できるのですが、ここで返しているのはreadsの中にwritesがあり、更にその中にtimeoutがある配列を返しているんでしょうか?

手元の本に「selectはリクエストを受信すると、リクエストを検出したソケットだけをリストに返します。」とあるのですが、ここで言うソケットとは入力、出力、例外を指していて、リストというのはつまり配列のことなんでしょうか?

Aベストアンサー

a = hoge.select(ARGS)

の場合に、ARGSの部分が引数です。
ここは、「reads[, writes[, excepts[, timeout]]]」とかかれているので
以下の4種類の書き方ができます。
hoge.select(reads, writes, excepts, timeout)
hoge.select(reads, writes, excepts)
hoge.select(reads, writes)
hoge.select(reads)

また、aに代入される値が戻り値です。
ここには、
「戻り値は、timeout した時には nil を、そうでないときは 3 要素の配列を返し、その各要素が入力/出力/例外待ちのオブジェクトの配列です(指定した配列のサブセット)」
と書かれているので
nil 若しくは [???,???,???]の形で値が代入されます。

これでご理解いただけるのではないでしょうか。

QVisualC++でコンパイル、Linuxサーバ側で実行

プログラムの勉強をしている者です。

最近、

「Windows側でVisualC++を利用してコンパイルし、それをLinuxに持っていって、Linuxサーバで実行する」

という、話を聞きました。

調べてみると、「クロスコンパイル」というものに該当しそうだと思うのですが、まったく理解できません。

Windows側の.exeファイルをそのままLinuxに持っていっても当然実行できないのに、なぜ、上のようなことができるのか不思議です。

どなたか、教えてください。

Aベストアンサー

VCで普通にコンパイルをすると、実際にはcl.exeというコンパイラが使われます。
これは、Windows用です。但し、VCのIDEは、使うコンパイラを設定することができます。
例えばLinux用のクロスコンパイラを用意して(VC自体には付属してません)使えばOKです。

通常のコンパイラは、自分の動作環境と出力オブジェクトの動作環境が同一ですが、
クロスコンパイラは、自分とは違う動作環境用(ここではLinux)のオブジェクトを作ります。

これは、Linuxで普通のコンパイラを使った場合と、同様なexeを作れるということです。
但し、作れるというだけで、Windows ではそのまま動かないものになります。

# 提示の条件だけだと、Linux サーバ上で Windows のエミュレーション環境が動いてる可能性もありますが…。

Qソケットプログラミングで・・

簡単なソケットプログラムを作ろうとしておりまして、サイトで調べたりしておりましたところ、なんとか分かってきたのですが、ひとつどうしてもわからないことがありますので教えていただけますでしょうか。
ソケットから受信するメッセージの生成のところなんですが、
「WSAAsyncSelect(m_socket,m_hWnd,WM_USER_ASYNC_SELECT,FD_READ | FD_WRITE)」
で、2番目の引数「m_hWnd」がわかりません。
教えていただけないでしょうか?よろしくお願いします。

Aベストアンサー

こちらの「III.非同期ソケット通信」のところが参考になりませんか?
WSAAsyncSelect()で、例えば受信データありの場合にイベントとして通知する
ウィンドウのハンドルをここに記述しておき、そのウィンドウのイベント
ハンドラで受信処理を行なうようなプログラミングを可能にします。
http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

参考URL:http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

QUDP通信での受信方法について

MFCでUDPプロトコルを使ったサーバー・クライアントをソケットプログラムで書いております。

ソフトの内容は、クライアントから送信されたの文字列のコマンドをサーバで処理をするだけです。

サーバー側での受信の仕方は
WSAAsyncSelect()関数を使ってソケットイベントが発生するごとに親ウィンドウに自作のメッセージ(WM_MY_MSG)が送られるように設定する



WM_MY_MSGのメッセージハンドラ内でrecvfrom()関数を使って受信する。

という方法を用いています。クライアント2台ぐらいであれば正常に動きます。


質問1:
まだ試したことはないのですが(というより試す環境がない)、ほぼ同時ぐらいに複数(10台ぐらい)のクライアントからコマンドが送信された場合、それを全部正確に受信できるものなのでしょうか?要するに一つのコマンドを処理中に別のコマンドが送られてきた場合の動作はどうなるのでしょうか?

質問2:
UDP通信での受信をする場合の何かもっとスタンダードな方法があるのでしょうか?

よろしくお願いします。

MFCでUDPプロトコルを使ったサーバー・クライアントをソケットプログラムで書いております。

ソフトの内容は、クライアントから送信されたの文字列のコマンドをサーバで処理をするだけです。

サーバー側での受信の仕方は
WSAAsyncSelect()関数を使ってソケットイベントが発生するごとに親ウィンドウに自作のメッセージ(WM_MY_MSG)が送られるように設定する



WM_MY_MSGのメッセージハンドラ内でrecvfrom()関数を使って受信する。

という方法を用いています。クライアント2台ぐらいであれば正常...続きを読む

Aベストアンサー

普段はMFCのSocketではなく
Winsockを使っていますが基本は同じだと思いますので参考までにコメント致します。

質問1:
同時に複数のクライアントからUDPパケットが送信された場合、
データはまず受信側のSocketのキューに格納されます。
なので1つのコマンドを処理中に別の(次の)コマンドを受信しても問題ありません。キューに格納されます。
シーケンシャルにキュー内からコマンドを取り出し終えるまで同じ処理を続ければ良いかと。

質問2:
MFCのSocketは古いVersionのSocketで、
困った記憶があります。v1.1?
(最新情報ではないかもです)
Winsockに関する良い書籍が出てますので
そちらを直接利用されてはどうでしょうか?
http://bookweb.kinokuniya.co.jp/htm/4797306882.html

UDPはコネクションレスですし、難しいことはないと思います。

参考URL:http://bookweb.kinokuniya.co.jp/htm/4797306882.html

普段はMFCのSocketではなく
Winsockを使っていますが基本は同じだと思いますので参考までにコメント致します。

質問1:
同時に複数のクライアントからUDPパケットが送信された場合、
データはまず受信側のSocketのキューに格納されます。
なので1つのコマンドを処理中に別の(次の)コマンドを受信しても問題ありません。キューに格納されます。
シーケンシャルにキュー内からコマンドを取り出し終えるまで同じ処理を続ければ良いかと。

質問2:
MFCのSocketは古いVersionのSocketで、
困った記憶...続きを読む

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

QVisualC++.NETかVisualC#.NETか

こんにちは。

今、VisualBasic6でプログラムをしています。今回、VBを卒業してCを勉強したいと思っているのですが、VisualC++.NETとVisualC#.NETの違いがいまいち分かりません。というか、.NETという物自体が分かっていない初心者です。VB6ではランタイムが必要でしたが、この2つではどうなのでしょうか?ちなみにVB歴約2年です。
.NETの基本的なことから教えていただけると非常に助かります。

回答よろしくお願いします。

Aベストアンサー

>ということは、私たち開発側は.NET Frameworkのことを特に意識して開発しなくても良いというわけですよね?

今のところ、Windows XP 以外の OS では、ServicePack をインストールしても、.NET Framework はインストールされません。

この問題を解決する方法の1つは、MSI (拡張子が .msi のセットアップファイルを見たことありませんか?)に対応したインストーラを作成し、.NET Framework のマージモジュールを組み込むというやりかたがあります。
しかし、わざわざインストーラを作るほどの事でもない場合も多いので、その場合は、.NET Framework をインストールしてくれと言うしかありません。

また、C言語のランタイムに関しても、DLL 版のランタイムをリンクすると実行できないという問題が発生します。こちらの問題は、SPx 以上が入っていれば OK、IE xx 以上が入っていれば OK、.NET Framework が入っていれば OK のような事で解決できそうです。これは、1つ前の VC++6.0 にも同じような事が言えます。

とまぁ、あまりいい状況ではありません。.NET Framework も、Windows 98 以降で IE 5.01 以上が必須なので2重に困ったりもしますが、時が解決してくれるだろうと楽観視しています。(回答になっていませんね)

あと、意外と知られていませんが、Visual 開発環境こそありませんが、.NET Framework SDK (無料)をインストールすると、Visual *** Standard 版と同じコンパイラ(C++, C#, VB.NETなど)もインストールされます。勉強の為にフリーのコンパイラを探している人には悪くない選択です。

>ということは、私たち開発側は.NET Frameworkのことを特に意識して開発しなくても良いというわけですよね?

今のところ、Windows XP 以外の OS では、ServicePack をインストールしても、.NET Framework はインストールされません。

この問題を解決する方法の1つは、MSI (拡張子が .msi のセットアップファイルを見たことありませんか?)に対応したインストーラを作成し、.NET Framework のマージモジュールを組み込むというやりかたがあります。
しかし、わざわざインストーラを作るほどの事でもな...続きを読む


人気Q&Aランキング

おすすめ情報