• ベストアンサー

WinSockでのソケット通信

早速質問ですが、 今、クライアントからの要求をサーバに投げ、 ページ事のデータをサーバから取得し、 クライアントに表示する。と言うシステムを作成中ですが、 1ページ目の処理中に次の要求を行なうと、 (一度目のrecv()を追い越して二回目のsend()を行なう?) ポートを掴んだままになってしまい処理の続行が出来なくなってしまっています。 色々調べましたが、非ブロッキングには設定していない(ioctlsocket関数をコールしていない) と思われます。 このような状況についてご存知の方がいらっしゃったら、是非お力をお貸し下さい。

  • jun_j
  • お礼率78% (56/71)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

jun_j 様 問題となっているプログラムが掲載されていないため、 問題点を指摘することは出来ません。 以下は、アドバイスです。参考になればと思います。 1.ソケット作成時に、setsockopt関数で、SO_REUSEADDRを使用してみては いかがでしょうか? 2.ポートを指定しないでソケットを作成し、サーバーに接続すると、 Windowsが自動的に空いたポートを使用します。 同じソケットハンドルを使用すれば、もちろん受信も出来ます。 その場合、サーバー側では、recvfrom関数で、どのポートを使用したか 確認し、そのポートにデータを送信します。 これにより、ポートの取り合いにはならないと思います。 なお、クライアント側では、getsockname関数で、使用している ポート番号を取得することができます。

jun_j
質問者

補足

すみません。 なんとか自己解決を目指します。

関連するQ&A

  • ソケット通信にてサーバ日時を取得する方法?

    ソケット通信にて(send及びrecv)でクライアントからサーバのタイム情報を取得する方法はありますか?

  • WinSockのクライアント処理

    WinSockについてお尋ねしたいのですが、 クライアントからのサーバへ1頁分のデータを要求しそれを画面に表示する プログラムを作成していますが、 一ページ分の要求毎に、以下の一連の処理を行っています。 WSAStartup socket connect send recv closesocket WSACleanup この為か、netstrtで確認すると"TIME_WAIT"が多数発生しポートが あふれてしまう事があります。 そこで、私は、 WSAStartupとWSACleanup を、クライアント起動時に行う。 (いろいろ調べると、これは絶対修正すべきという事がわかりました。) もうひとつ、 "TIME_WAIT"への対処として、 socket connect も、クライアント起動時に行う事を考えています。 私の考えは適切なのでしょうか? "TIME_WAIT"への一般的な対処などお教えください。 宜しくお願いいたします。

  • ソケットを使ったTCP通信

    はじめまして. 最近ネットワークの勉強を始めた学生です. ソケットを使ったTCP通信について質問させてください. クライアント側はsocket(), connect()でコネクションを確立した後に何回か連続してsend(), recv()を行いたいのに,サーバ側がファイアウォールや侵入検知システムを使って途中で通信を終了するようにしてしまっている場合,クライアント側は再びコネクションを確立させなければ全てのsend()を行うことはできないのでしょうか? よろしくお願いします.

  • if文の中ではwinsockのsendが出来ない?

    struct C_Commu { ----WSADATA wsadata; ----SOCKET Sock; ----sockaddr_in Addr; public: ----void Init(); ----void Send(); } というクラスがあったとします。 Init()ではソケットの生成だとかWinsockを使った通信で必要な設定を行っています。(TCPとする) void C_Commu::Send() { ----send( Sock, "hello", 5, 0 ); ----if(何らかの条件) ----{ --------send( Sock, "hello", 5, 0 ); ----} } このような関数の場合に、if文の外のsend()をコメントアウトしたりコメントにしたりして動作を確認してみたところ if文の外のsend()にはサーバーが反応するのですが、if文内のsend()はsend()が行われているのが確認されるのにもかかわらずサーバー側が一切反応しません。 ここでいう、サーバーが反応するとは、select()を用いてブロッキングが解除されてrecv()に処理が回れば反応した、recv()に処理が行かなければ反応していない、としています。 これはどうしてでしょうか?

  • ソケット通信処理について

    現在、下記のようなクライアント、サーバ通信を行っております。 [クライアント] (a)WSAStartup (b)socket (c)connect (d)send(サーバへの要求送信) (e)recv(サーバからの応答受信) (f)shutdown (g)closesocket (1)プロセスは、常駐している (2)(a)は初回起動時1回のみ (3)通常(d)~(e)を周期的に行う (4)(e)にて一定時間経過した場合、5秒待ち6回リトライし、それでもだめな場合は、(f)(g)を実施後(b)から処理を行う。この後、WSACleanupを行っていない。プロセス終了(exit)もしていない。 [サーバ] (a)socket (b)bind (c)listen (d)accept (e)子プロセス生成 以下子プロセス処理 (f)select (g)recv(クライアントからの要求受信) (h)send(クライアントへの応答送信) (1)親プロセス((a)~(e)を行うプロセス)は常駐している。子プロセス起動後、(d)でconnect待ちとなる。(クライアント側からの再接続待ち) (2)子プロセスは、通常(f)~(h)の処理を行い、(f)又は(g)の異常時にexitする。 この処理で、クライアント処理(e)の一定時間経過後の再接続が正常に動作しない場合があります。 詳細情報を取得していませんが(現実的にすぐに詳細情報を取得することができない状況)(c)にて異常が発生していると思われます。 一度その状態になると二度と再接続できなくなり、マシン再起動(プロセス再起動)で復旧させることになります。 (実際は、マシン再起動後に再接続が正常になることを確認しています。(プロセス単体の再起動での確認はしていません。)) そこで質問ですが、 (1)再接続時、WSACleanupを行っていないが、問題ないか(処理の順番:(f)→(g)→(b)) (2)再接続前にプロセス終了(exit)していないが、問題ないか (3)上記の作りで考えられる要因として、何があるか ご教示して頂きたく、宜しくお願い致します。

  • UDP/IPでのソケット作成について(winsock)

    UDP/IPでのソケット作成について(winsock) 開発環境VC++.NET、O/S WIN2000にてソケットプログラミング(winsock2.0)をしています。 コンソールプログラミングではありませんが、WindProcは持っていません。 UDPサーバーを作り、複数クライアントの対応をしたいと考えています。 クライアントAからの通信やりとり中に クライアントBからの通信がきたら、そちらとも通信やりとりを(自動で)行いたい。 ここで問題なのが、クライアントAの要求ポートが15000で、 クライアントBの要求ポートも15000なのです。 同じ既に開いているポートでソケット作成しようとしても、socket()関数はエラーを返してくるのですが、 やり方を工夫すれば、同一ポートでの複数クライアント対応は可能なのでしょうか。不可能なのでしょうか。 可能であれば、やり方、ヒント等教えてください。よろしくお願いします。 追記 (1)TCP/IPでは、同一ポートでソケット作成が可能でした。ネットで探したサンプルプログラムが  そのような動きをしていたのですが、UDPに書換えることはできませんでした。  http://eternalwindows.jp/network/winsock/winsock04s.html (2)UNIXの場合fork()処理後に socket()作成 → bind()で同一ポートでの複数クライアント対応が  上手くいくらしいのですが、Windowsではマルチスレッド等をうまく活用すれば、  fork()と同様の処理が可能になり、目的が達成できるでしょうか。

  • winsockでファイル転送

    教えてください。 windockを使いファイルをサーバ側からクライアント側に転送したいのですが、テキストファイルfgetsで一行ずつ読み込んで、それをsendで転送し、クライアントでrecvで読み取り、テキストファイルに書き出す。 という一連の流れより、もっと簡単に、ファイルを転送する方法又はMFCの関数等ありますか? [環境] visual C++ 6.0 MFC

  • Javascritpでソケット操作

    javascriptで自サイトの特定のポート、例えば25ポートを使ってメールの情報を取得したいのですが、可能でしょうか? 自サイトの開いているポートをソケットで操作したいです。 80ポートはwwwなのでAjaxを使えばOKと思いますが、それ以外のポートの場合httpでなので、直接ソケットで操作したいです。 クライアント機能で、オープン・クローズ・send, recvなどで簡単に操作したいです。

  • winsock windowprocでFD_WRITEの処理

    すみません。よくわからなくなったので教えてください。 非同期処理を行いwindowprocで送信、受信の処理をしているのですが、一部わかりません。 [内容] クライアントからデータを送信してもらい、サーバ側で受信をして、サーバ側で受信後、クライアントへ送信をしたいのですが.... [サーバ側ソース抜粋] ::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { int EventErrorCoode; int len; switch(message) { case FM_TCPPROC: EventErrorCoode = WSAGETSELECTERROR(lParam); switch(WSAGETSELECTEVENT(lParam)){ case FD_CONNECT: //コネクトされたときの処理 break; case FD_ACCEPT: if(EventErrorCoode != 0){ NetWork_LogOut(); break; } // 状態判定処理 if(NetWork_Accept() == FALSE){    //失敗したときの処理 } break; case FD_READ: // データの受信メッセージ if(NetWork_Recv() == FALSE){   } break;  case FD_WRITE: //テスト折り返し送信  SendData = "折り返し";  strcpy(Recv_Buffer,SendData);  len = send(server_s, Recv_Buffer, strlen(Recv_Buffer),0); break;    :    : return CDialog::WindowProc(message, wParam, lParam); } ::NetWork_Recv() { int nResult; int len; nResult = recv(client_s, (CHAR *)Recv_Buffer, RECV_SIZE - 1, 0); Recv_Buffer[nResult] = '\0'; return TRUE; } *非同期処理はsocket作成後しています。 クライアントから送信されたデータが、FD_READで認識し、NetWork_Recv()関数を使って受信します。 その後、空になった時点で、FD_WRITEを実行すると思っていたのですが、recvされた後、データは空にならないのでしょうか?

  • ソケット:書き出しをソケット経由で読み込みできない

    お世話になります。 今、Javaでのソケットプログラミングについて学習をはじめて、はじめてのサンプルプログラムが失敗しました。 そこでもうちょっと簡単にしてみたのですが(一部の抜粋が以下のソースです)、またまたうまくいきません。 エコーサーバのテストなのですが、client : after send messageと表示されたところで処理が止まってしまいます。 結果は最下位に貼り付けてあります。 どうかよろしくお願いします。 // reader/writerの取得 BufferedWriter clientWriter = new BufferedWriter( new OutputStreamWriter(sockClient.getOutputStream()), BUFFERSIZE); BufferedReader clientReader = new BufferedReader( new InputStreamReader(sockClient.getInputStream()), BUFFERSIZE); BufferedWriter serverWriter = new BufferedWriter( new OutputStreamWriter(sockServer.getOutputStream()), BUFFERSIZE); BufferedReader serverReader = new BufferedReader( new InputStreamReader(sockServer.getInputStream()), BUFFERSIZE); // サーバのローカルとクライアントの接続先が同じことの確認 System.out.println("client port : " + sockClient.getPort()); System.out.println("client addr : " + sockClient.getInetAddress().getHostAddress()); System.out.println("server port : " + sockServer.getLocalPort()); System.out.println("server addr : " + sockServer.getLocalAddress().getHostAddress()); // クライアント→サーバー→クライアントの順にmaaaaaいうえおを送信 String strMessage = "maaaaaいうえお"; System.out.println("client : send message : " + strMessage); clientWriter.write(strMessage); System.out.println("client : after send message"); String msgGet = serverReader.readLine(); System.out.println("server : got : " + msgGet); serverWriter.write(msgGet); System.out.println("client : got : " + clientReader.readLine()); ------------以下が結果------------- client port : 4544 client addr : 127.0.0.1 server port : 4544 server addr : 127.0.0.1 client : send message : maaaaaいうえお client : after send message

    • ベストアンサー
    • Java

専門家に質問してみよう