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で質問しましょう!
似たような質問が見つかりました
- ネットワーク 社内ネットワークの1台だけ接続できないときがある 4 2023/01/25 11:58
- サーバー (童顔♀です)webサイト納品後,記事更新をこちらでする場合どうやりますか....? 3 2023/08/09 04:44
- サーバー Webページに繋がるまでの流れについての質問です。 2 2023/03/19 23:15
- オンラインゲーム フォトナのエラーで遊べません 3 2022/05/06 07:17
- サーバー Webサイト構築フリーランスの案件受注について 1 2022/03/27 18:16
- UNIX・Linux OpenSSHのサーバー設定ファイルsshd_config内のHostKey行について 4 2023/05/02 09:53
- ネットワーク 自分のPC(ローカル環境)から,Webページにアクセスする過程についての質問です。 1 2023/03/19 23:00
- UNIX・Linux いつの間にか自宅サーバーが見れなくなっていた時のトラブルシューティング手順をご教示ください 4 2023/02/15 21:01
- Windows 10 リモートデスクトップ フォント 2 2023/08/19 18:07
- サーバー HP制作をしている方、納品後のデータについて 2 2023/04/12 19:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のよるrsh-clientの簡潔...
-
TCP/IP通信時のサーバーからの受信
-
ソケットのクローズについて
-
Winsockで接続待ちタイムアウト...
-
Winsockを使わずにVBでSocketを...
-
UDP通信におけるbind関数について
-
メールサーバへの接続タイムア...
-
ソケットのrecvの戻り値が0
-
WinSockでチャット
-
Socket通信の0バイト受信について
-
WinSockでの通信プログラムがう...
-
Java(クライアント)とC言語(サ...
-
ソケットプログラミングに関す...
-
ポート番号0について
-
WINSOCKのWSACleanupについて
-
UdpClient 送信元のIPアドレ...
-
異なる言語間でのソケット通信...
-
同じLAN内パソコンのIPアドレス...
-
TCP/IP通信型プログラムです。 ...
-
winsockを使った通信での同時接...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットを用いた1対多通信につ...
-
UdpClient 送信元のIPアドレ...
-
ソケットでクライアントのipア...
-
UDP通信する時に、相手にどうや...
-
ソケット通信 同じポート番号...
-
同じLAN内パソコンのIPアドレス...
-
Connectエラーが出てしまう・・...
-
ソケットのクローズについて
-
CreateFile関数でCOMポートが開...
-
異なる言語間でのソケット通信...
-
C言語でHTTP1.1のキープアライ...
-
送信したデータの一部が文字化...
おすすめ情報