
No.3ベストアンサー
- 回答日時:
#1です。
>TCPはトランスポートプロトコルです。
そのとおりです。すみません(^^;
FTPって書いたつもり・・・だったんですけどね(笑)
>プロトコルの作成方法がいまいち掴めなくて
まず、TCPの特徴として
・データの送受信は保証される(UDPはされない)
・しかしデータの受信タイミングは一括とは限らない
ということを覚えておきましょう。
例えばクライアントに「こんにちわ」という文字列を送信した場合、「こんにちわ」一発で届くかもしれませんし、「こんに」「ちわ」と2度で届くかもしれません。(こんなに短い文字列だとほぼ100%一発受信ですが)
また「こんにちわ」「元気ですか」と2回送信した場合に「元気ですか」「こんにちわ」とひっくり返ることはありません(到着順序の保証)。
なので、プロトコルを作成する場合「どこからどこまでがデータの始まりで、データの終わり(ターミネータ)なのか」が分かればいいのです。
例えば#2さんの場合だと「CRLF(改行コード)」がターミネータのようですね。
逆に受信側ではバッファを見て「CRLF」までをワンブロックとして処理すればいいわけです。
プロトコルというと難しく感じますが、その名のとおり「データをどのように処理するか」という決まり事ですので、問題が無ければ別にどんな方法でも構わないんです。
この回答への補足
レス有難うございます。
プロトコル作成でスタックを使用しても問題は無いのでしょうか?
例えば
std::stack<int> st;
st.push( 10 );
st.push( 'あ' );
とスタックの中に入れて
送信;
send(Sock,reinterpret_cast<char*>(&st),sizeof(st),0);
受信:
recv(Sock,reinterpret_cast<char*>(&st),sizeof(st),0);
受信後にスタックの中を順に取り出し表示
cout << (int)st.top() << ", ";
st.pop();
cout << (char)st.top() << ", ";
st.pop();
これでも一応、始まりと終わりが判るとは思うのですか、
こういうのでも、プロトコルといえるのでしょうか?
宜しくお願いします。
No.4
- 回答日時:
>プロトコル作成でスタックを使用しても問題は無いのでしょうか?
問題ないと思いますけど・・・?
ただ、スタックって基本的にFILO(先入れ後出し)な構造の時使うものなのでこの場合は不適ですよ。SocketのバッファはFIFO(先入れ先出し)なデータ構造と考えないと・・・。
>これでも一応、始まりと終わりが判るとは思うのですか、
わからない・・・と思いますけど。
>こういうのでも、プロトコルといえるのでしょうか?
うーん、良く伝わってなかったようですね(^^;
最初の質問の「サーバーに接続している全てのクライアントを(各クライアントに)教える」という目的は置いておくとします(^^;
例えば、#2さんのアドバイスを流用して、クライアントは常に「ユーザー名<CRLF>メッセージ<CRLF><CRLF>」というデータ投げるようにします。こういうのがプロトコル(決まりごと)ですよ。
各クライアントはこれを(プロトコル通りに)解析するだけです。
ですので(最初の質問を無視するなら)サーバ側は各クライアントから送られたデータをそのままマルチキャストしてやれば良いだけ、ということになりますね。
そして最初の質問を実現するなら
サーバ側からクライアントに「接続者全リスト」を送る必要は全く無く、各クライアントがリストを保持しておき、サーバから接続/切断情報を受け取った時にその都度更新する
という方式のほうが(サーバが)軽くていいと思います。
で、クライアントが接続/切断した場合は
「svr<CRLF>ユーザー名<CRLF>接続状態<CRLF><CRLF>」
というデータをサーバから送る、とします。
クライアントは先ほどと同様にデータを解析しますが、先頭が「svr<CRLF>」で始まってますから、サーバからのメッセージだと言うことを理解できますよね。
(ユーザー名に「svr」を使わないのが前提ですが)
ここまで書けば・・・分かると思うんですが(^^;
この回答への補足
レス有難うございます。
プロトコルは理解する事が出来ました^^;
> 各クライアントがリストを保持しておき
最初の質問に戻ってしまうのですが
クライアントがリストを保持するタイミングが判らないのですが・・・
最初の接続時にサーバーから接続者リストをもらう訳ですよね。
サーバーは各クライアントのIPとポート番号はどうやって取得しておくのでしょうか?
クライアントがサーバーに対して申告でしょうか?
それとも
otu_otuさんが仰るように
サーバーのソケットのハンドルをクライアントに
渡せば良いのでしょうか?
No.2
- 回答日時:
全クライアントをサーバから取得するとはどうゆうことでしょうか?
サーバはクライアントと接続されているわけですから、ソケットのハンドルを持っていますよね?そのハンドル自身がクライアントだと考えてはいけないのですか?
もし、クライアントにそれぞれ名前をつけたいのであれば(例えば「Hideya」とか「Goo」など)、まずクライアントからサーバにそれを教える手段を確保しなければなりません。
たとえば、接続の際に、次のような情報をクライアントから、サーバに送るといいでしょう。
Name: Hideya<CR><LF>
<CR><LF>
サーバ側では接続が確立しているあいだ、その名前を保持させます。これで、サーバによるクライアント名の管理はできますよね。
一方で、maxpowerさんの目指しているのは、サーバに保持されているクライアント名のリストを、何らかの手段でクライアントから取得したいのですよね。
それであれば、クライアントからサーバに
Who are login?<CR><LF>
<CR><LF>
と送り、それを受信したサーバが、
The Member Count: 12<CR><LF>
Name: Hideya<CR><LF>
Name: Goo<CR><LF>
・
・
・
<CR><LF>
のように、応答するようにしてはいかがですか?
TCP上でチャットシステムを作るのであれば、プロトコルを作成しなければいけません。
#1の方の補足ですけれど、HTTPは確かにアプリケーションプロトコルですが、TCPはトランスポートプロトコルです。
この回答への補足
>> 全クライアントをサーバから取得するとはどうゆうことでしょうか?
マルチキャストを行いたいので、サーバーに接続している全てのクライアントの情報(IPや名前)を取得し
特定のクライアントにメッセージを送信するように
したいと思っています。
TCP上でチャットを作りたいのですが
プロトコルの作成方法がいまいち掴めなくて
困っています。。。
No.1
- 回答日時:
>現在接続している全クライアントをサーバーから取得する関数
それはサーバの仕事だと思いますが(^^;
少なくともサーバは「どのクライアントが接続(切断)したか」は知っているわけですから、サーバが各クライアントに必要に応じて情報を送ってやればいいのです。
>チャットを作成するまでは出来たのですが
ただ単に文字列を垂れ流すだけ・・・になってるんではないでしょうか?
いわゆる「アプリケーション層」のプロトコル(例えばHTTPやTCP)を設計すべきだと思います。
検索してみると・・・
http://www.ie.u-ryukyu.ac.jp/~j00043/network/pro …
こんな感じでもいいですね。
参考URL:http://www.ie.u-ryukyu.ac.jp/~j00043/network/pro …
>> ただ単に文字列を垂れ流すだけ・・・になってるんではないでしょうか?
仰るとおりです。
垂れ流しになっていると思います。
>> いわゆる「アプリケーション層」のプロトコル(例えばHTTPやTCP)を設計すべきだと思います。
WinSockを使えば、TCP/IPにの設計を気にする必要など
ないと思っていました・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
Socket通信の0バイト受信について
-
socket.hを入手するには?
-
VB6‥ソケットについて
-
CreateFile関数でCOMポートが開...
-
ソケットのクローズについて
-
closeされたsocketへの動作につ...
-
Macターミナルで実行中のプログ...
-
C# シリアル通信でデータ受信...
-
VBSの処理中一旦処理を止めて再...
-
バックグラウンドのプロセスの...
-
VBA kernel32 の意味
-
エクセルVBAでクリップボード内...
-
VB6.0 SHELLで起動...
-
【MFC】イベントの無効化について
-
マイコンからプログラムを読み...
-
ACCESS側からEXCELの書式を設定...
-
プリントスクリーンをプログラ...
-
VBSで応答不要のメッセージボッ...
-
初回接続の遅い原因について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
VB6のwinsockでconnectできない
-
Socket通信の0バイト受信について
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
Connectエラーが出てしまう・・...
-
送信したデータの一部が文字化...
-
【ajax】 XMLHttpRequestオブジ...
-
ソケット通信
-
closeされたsocketへの動作につ...
-
wsdlからのサービス化を行い。
-
Cにおける通信プログラミングの...
-
UdpClient 送信元のIPアドレ...
-
非ブロッキングソケットのrecv...
-
ソケットを用いた1対多通信につ...
おすすめ情報