HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0725
secondpcbnet2について8解決


second

リンク

2010/7/25(Sun) 01:30:27|NO.33910

pcbnet2 を使用して
チャットプログラムを作っているのですが
どうしても1つのポートにいくつかのソケットを設けたいのですが
私が組んだプログラムではソケットが3つ設けた時点で
2人目の接続の際のニックネームの送信がうまくいかなくなりました
で1つだけにソケットをしてみるとうまくいきます
ここで質問なのですが

やはり1つのポートにいくつもソケットを設けるものではないんですか?
↑私はさきほどいったように3つのソケットを設けたら送受信が出来なくなりました

となると3つのポートで通信を行うということは可能でしょうか?
↑1度プログラムを組んでみようと思ったのですが挫折しました

1つのソケットを使って用途の違う受信文字列をどうにかして分けることは出来ますか?
例 チャットの内容 が ソケット1に送られてきたのをmesboxに表示
  チャットのメンバーのリスト が その後におくられてきたのを リストボックスに表示
  のようにこの送られてきたデーターはこういうものだという見分けるプログラムがよくわかりません

すみません最後の質問は説明が意味不明になってしまっているかもしれませんが
体験談などもお聞かせください



この記事に返信する


Ve

リンク

2010/7/25(Sun) 01:58:21|NO.33911

付属のサンプルのチャットスクリプトでもソケットは3つまででしたか?

3つまでなら環境のせいもあると思いますが…。(理由までは分かりません)
3つ以上接続が確立するなら、どこかで間違っているのかと。



second

リンク

2010/7/25(Sun) 08:51:56|NO.33912

表現が少しおかしくなってしまっていました
新たにわかったことを踏まえて詳しく言うと
サーバープログラムではいくつソケットを設けてもなんら問題はないのですが
クライアントに2つ3つとソケットを設けるとクライアントの送受信に問題がでるみたいなんです
これはサンプルの部分をいじって調べてみたのでスクリプトには問題はなさそうです
で、ポート3つを開放し通信を試みたんですが、やはり同じようにクライアントに問題が
結果から言うとクライアントには複数の通信は向いていないということになるんですかね
ということは送られてきたデーターをどうにかして見分けて分岐させ処理するしかないんでしょうかね
でも、どうすればいいかまったくわかりません



Ve

リンク

2010/7/25(Sun) 09:47:15|NO.33915

C/S型じゃなくてP2P型のネットワークモデル?

後、接続が確保されていて、送受信に問題がある場合は
やっぱりソースの中に問題があるかな。

どんな症状なのか全くわからないけど。



second

リンク

2010/7/25(Sun) 10:32:45|NO.33916

C/S型です
どんな症状かといいますと
手順をおって説明すると

クライアント                  サーバー                    ポートを開放して接続待機 仮にポート50000開放                        ↓ 相手のサーバープログラムに接続 →→→→ 接続を待つ  仮にポート50000に接続            ↓     ↓              新たに開放したポートにソケットを設ける 仮にsocke1,socket2,socket3                        ↓ 接続の承認を待つ ←←←←←←←←←← 接続を承認          ↓        送れる       ↓           ←○←←←←←←←←  データーを送受信 送れないor受信しない データの送受信      仮にsocket1 →×→→→→→→→→ socket2 socket3



second

リンク

2010/7/25(Sun) 10:58:24|NO.33919

いちどサンプルを提示しますので皆さんのPCで確認していただけないでしょうか
今回1つしか実際には使っていませんが3つのソケット同士が繋がっていると私の場合
クライアントの名前の送信がうまくいかなくなります
そしてサーバーの名前の受信部分で永遠に回ってしまします
もしも私と同じ症状になったら//で囲ってある3部分を消して
実行してみてください私はそれで正常になったのですが

実際このようなソースの書き方はおかしいのでしょうか??

クライアント


;----------送信ボタンでテキストを送信するタイプ #include "pcbnet2.as" #define SERVERPORT 50000 #define VER "1.0" sdim recivedata,200;データを受信する sdim recivename,20;受信したデータから名前を取り出す sdim recivetext,50;受信したデータからテキストを取り出す ;--------名前などの定義------------------ username="TEST_USER";デフォルトの名前 serverIP="127.0.0.1";同接続先 screen 0,320,135 title "RSCS Ver."+VER+" START" syscolor 15:boxf color 0,0,0 mes "利用するユーザーネーム" input username,320,20,20 mes "サーバーのIPアドレス" input serverIP,320,20,0 objsize 320,60 button "GO",*start stop *start screen 0,640,240 notesel chatlog syscolor 15:boxf mesbox chatlog,640,220,0 boxID=stat chatmes="サーバーに接続を開始します。":gosub *writetext2box ;------------------接続開始---------------------------------- tcpopen socket,serverIP,SERVERPORT ///////////////////////////////////////////////////// tcpopen socket2,serverIP,SERVERPORT ////// tcpopen socket3,serverIP,SERVERPORT ////// ///////////////////////////////////////////////////// repeat tcpiscon socket if stat!0:break await 1 loop ///////////////////////////////////////////////////// repeat /////////// tcpiscon socket2 /////////// if stat!0:break /////////// await 1 /////////// loop /////////// repeat /////////// tcpiscon socket3 /////////// if stat!0:break          /////////// await 1             /////////// loop /////////// ///////////////////////////////////////////////////// if stat=2:chatmes="--------------------------------\nサーバーとの接続に問題が生じました。5秒後に終了します!\n--------------------------------":gosub *writetext2box:wait 500:end chatmes="サーバーに接続しました。名前を送信":gosub *writetext2box tcpput username,socket;名前送信 ;--------------------------------------------------------------- chatmes="--------------------------------\n認証が完了しました。チャット開始\n--------------------------------":gosub *writetext2box mytext="" input mytext,540,20,50 inputboxID=stat objsize 100,20:pos 540,220:button gosub "送信",*sendtext title "Really Simple Chat System Client Ver."+VER+" Your name is \""+username+"\"" *main ;----------------------華麗なるメインループ-------------------------------------- gosub *waittext;サーバーからデータが来てないかチェック await 10 goto *main ;----------------------終わり---------------------------------------------------- *waittext tcpfail socket;エラーチェック if stat!0:{;エラーが生じた chatmes="--------------------------------\nサーバーとの接続に問題が生じました。5秒後に終了します!\n--------------------------------":gosub *writetext2box:wait 500:end } tcprecv recivedata,0,70,socket if stat!0:{;テキストが来ている unpack recivedata,"a20a50",recivename,recivetext chatmes=""+recivename+" : "+recivetext+"":gosub *writetext2box } return *sendtext tcpput mytext,socket;サーバーにテキストを送信 chatmes=username+" : "+mytext:gosub *writetext2box;自分のメッセージは帰ってこないので、自分でログに追加する mytext="" objprm inputboxID,"";入力欄をクリア objsel inputboxID;入力欄にフォーカスを移す return *writetext2box noteadd ""+chatmes+"",0 objprm boxID,chatlog return


サーバー

#include "pcbnet2.as" #define SERVERPORT 50000;ポートの定義 #define MAXUSER 100;接続を許可する人数(最大128までだと思う) #define VER "1.1";バージョン情報 ;---------ユーザーデータ領域の確保 sdim username,200,MAXUSER;ユーザー名 dim usersocketID,MAXUSER;ユーザーのソケットID dim usersocketID2,MAXUSER;ユーザーのソケットID dim usersocketID3,MAXUSER;ユーザーのソケットID dim uservalidflag,MAXUSER;有効かどうかのフラグ ;--------データ受信用領域の確保 sdim recivedata,200;多めに取っとく sdim senddata,200;同じく ;--------ログ表示用 sdim serverlog,4096 notesel serverlog ;--------------------------------------------- ;---------ウィンドウを作る----------- screen 0,640,240 title "Really Simple Chat System Server Ver "+VER+"" syscolor 15:boxf mesbox serverlog,640,240,0 boxID=stat ;---------通信待機開始 color 0,0,0 pos 0,0:servermes="ポート"+SERVERPORT+"で通信待機を開始します":gosub *writetext2box tcpmake opensocket,SERVERPORT if stat!0:servermes="待ち受けに失敗しました。ポートが使用中の可能性があります。\n終了します。":gosub *writetext2box:wait 300:end ;---------通信待機開始成功と画面初期化 servermes="通信待機を開始しました。":gosub *writetext2box *main gosub *waituser;ユーザー待機の確認処理 gosub *waittext;ユーザーからデータが送信されていないか調べる title "Really Simple Chat System Server Ver "+VER+" nowuser="+nowusercount+"" await 10 goto *main ;-------------サブルーチン達-------------------- *waituser tcpwait opensocket;受付用ソケットにユーザーが来ていないかチェック if stat=1 {;着てる errorflag=1 repeat MAXUSER;使われていないユーザーNoを検索 if uservalidflag.cnt=0:{ errorflag=0 blankID=cnt break } loop if errorflag=1:{;満員状態 } else:{ tcpaccept usersocketID.blankID,opensocket;接続を承認、ソケット作成 ////////////////////////////////////////////////////////////////////////////////////////////////// tcpaccept usersocket2ID.blankID,opensocket;接続を承認、ソケット作成 //// tcpaccept usersocket3ID.blankID,opensocket;接続を承認、ソケット作成 //// ////////////////////////////////////////////////////////////////////////////////////////////////// uservalidflag.blankID=1;有効フラグを立てる repeat //ここで名前の受信をずっと待っている tcpget username.blankID,64,usersocketID.blankID;ユーザー名を受け取る if stat!0:break loop username.blankID+="#"+blankID+"";ユーザー名にナンバーを追加 servermes=""+username.blankID+"さんが接続してきました":gosub *writetext2box } } return *waittext nowusercount=0 repeat MAXUSER if uservalidflag.cnt==0:continue tcpfail usersocketID.cnt;ソケットがエラー状態か調べる if stat!0:{;エラー状態 tcpclose usersocketID.cnt uservalidflag.cnt=0 servermes=""+username.cnt+"さんとの接続が切れました":gosub *writetext2box continue } ;------------------切断処理終了 ;------------------テキスト待ちうけ tcpget recivedata,200,usersocketID.cnt if stat!0:textowner=cnt:gosub *sendtext ;-------------------------------------------------- nowusercount++ loop return *sendtext pack senddata,"a20a50",username(textowner),recivedata;送信用データ作成 datasize=stat;データサイズを保存 sendcount=0 repeat MAXUSER if uservalidflag.cnt==0:continue if textowner=cnt:continue;送信者には送信しない tcpsend senddata,0,datasize,usersocketID.cnt sendcount++ loop servermes=""+username.textowner+":"+recivedata+" を"+sendcount+"人に送信":gosub *writetext2box return *writetext2box if gettime(1)<10:s1="0":else:s1="" if gettime(3)<10:s2="0":else:s2="" if gettime(4)<10:s3="0":else:s3="" if gettime(5)<10:s4="0":else:s4="" noteadd ""+gettime(0)+"/"+s1+""+gettime(1)+"/"+s2+""+gettime(3)+" "+s3+""+gettime(4)+":"+s4+""+gettime(5)+"-----"+servermes+"",0 objprm boxID,serverlog return



Ve

リンク

2010/7/25(Sun) 11:05:47|NO.33921

指定したポートで待ち受けるだけで開放とは少し違うかな。

サーバ側は

tcpmake lis1,PORT1 tcpmake lis2,PORT2 tcpmake lis3,PORT3
で待ち受けポートを3つ作る

tcpaccept soc1,lis1 tcpaccept soc2,lis2 tcpaccept soc3,lis3
の3つで受付

クライアント側は

tcpopen soc1,HOST,PORT1 tcpopen soc2,HOST,PORT2 tcpopen soc3,HOST,PORT3

こうするしかないかな…。

クライアントが複数のソケットを持つC/S型ネットワークプログラムは
組んだ事がないので、この方法ぐらいしか思いつきませんね。



リンク

2010/7/25(Sun) 12:17:07|NO.33925

ありがとうございます
ですが、おっしゃったとおりにポートを3つ使っても
うまくいきませんでした。
やはり送られてきた情報を分岐させて処理するしかないのでしょうか
ちなみに本当は通信ゲームにチャット機能がついているという感じにしたいのですが
1つはチャットの送受信
1つはメンバーリストの送受信
1つはゲーム関係の情報の送受信
という風に3つに分けたのですが



second

リンク

2010/7/25(Sun) 13:01:03|NO.33931

解決



ONION software Copyright 1997-2023(c) All rights reserved.