• 締切済み

winsockの動作について。

winsockの動作について、質問させていただきます。 (1)UDPのsendto()でWSAEADDRNOTAVAIL(10049)が発生する。 数十個(64個以内)のUDPソケットを用意し、for()ループで全てのソケットから送信した場合、途中からエラー(WSAEADDRNOTAVAIL)が発生してしまいます。 あて先のアドレス/ポートは全て同一なので、原因は別にあるのではないかと考えています。 sendto()と次のsendto()の間にスリープを入れると、WSAEADDRNOTAVAIL(10049)が発生しなくなるのは確認しました。 一度に処理できる数が決まっているといったような、制限があるのでしょうか? (2)TCPのconnect()に時間がかかる。 TCPクライアントのconnect()に30秒くらいかかる事があります。 connect()はノンブロッキングで実行し、その後にselect()を繰り返し呼んで接続の確認をしているのですが、その間にWSAGetLastError()でエラーを確認するとWSAEWOULDBLOCK(10035)となっています。 パケットをダンプすると"SYN"が送信されていないため、TCPクライアント側の問題だと考えています。 connect()が一瞬で成功する場合もあるため、なにか問題があるのではないかと思っているのですが、30秒くらいかかる場合もあるのでしょうか? ※(1)のUDPの送信処理を行った直後に、このTCPのconnect()を行うと時間がかかるような気がしています。 よろしくお願いします。

みんなの回答

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

(1)TCP/IPプロトコルスタックの内部バッファが埋まっているのでは? (2)(1)と同様にTCP/IPプロトコルスタックに処理が溜まっているのでは? 内部動作の詳細は知らないけどユーザプロセスとは別のプロセスだかスレッドだかで処理しているんじゃなかったかな。それだとプロセススイッチのオーバーヘッドを減らすため、呼び出しプロセスが待ちに入るまで実際の処理の開始を遅延していると思う。

heppokoP
質問者

お礼

回答、ありがとうございます。 勉強不足で、いまひとつ理解は出来ていないのですが。。 (1)については、setsockopt()で送信バッファのサイズを指定したところ、WSAEADDRNOTAVAIL(10049)が発生しなくなりました。 サイズに0を指定してバッファリングを無効にする、といったことも出来るようなので、いろいろ試してみたいと思います。

関連するQ&A

  • Winsockでの送信(TCP)

    Winsockでの送受信プログラムを作成しています。 システム構成としてはサーバーが1つあって、それに複数のPC(クライアント)を接続します。 そしてチャットのようにやりとりを行うプログラムを作成しています。 しかし、チャットと違う点は、文字を、指定した相手(IPで指定)にのみ送信するということです。 自分で調べた結果UDPを用いれば簡単だということを知りました。(sendtoで送信先IPが指定できるから) しかし、TCPのほうが信頼性が高いということでTCPでやりたいと思いました。(勉強にもなるので) どなたかやり方をご教授お願いいたします。

  • ソケットプログラミングについて_WinSock2

    コネクションの確立はlisten関数、accept関数、connect関数を用いて行い、パケット送信の場合は、UDPで送信するというプログラムを作成したいと思っています。 この場合、listen関数、accept関数、connect関数を使用する際は、TCPソケットをオープンするという形になるのでしょうか? それとも、listen,accept,connect関数は、UDPソケットオープンでよいのでしょうか? よろしくお願いします。

  • 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)

    こんばんわ。 VC++.NETにてコンソール上でソケットプログラミングをしています。 非同期モードとノンブロッキング関数について知りたいのですが、私は、今までTCPやUDPでsendtoやsend関数を使用してきました。しかし、非同期やノンブロッキング関数があることを知り、詳しく知りたいと思っています。 1.非同期やノンブロッキング関数はGUI作成を行う上では重要であるが、コンソール上でプログラミングを行っている場合は利用しなくてよいのでしょうか? 2.以下のWSAAsyncSelect関数の第2引数の設定がわかりません。サンプルでは、hwndに関連付けられたウィンドウがSM_EVENTメッセージを受け取りますと記述されていますが、ウィンドウを利用していないコンソールアプリでの記述方法はありますでしょうか? HWND hwnd; WSAAsyncSelect(Sock,hwnd,SM_EVENT,FD_WRITE); と記述し実行した場合、強制終了されてしまいます。 3.たとえば、送信側から送信したパケットを受信側で受信し、再度受信側から送信側へ送信する場合を考えると、 送信側で送信と受信が必要です。この場合、マルチスレッド処理が必要だと思うのですが、非同期のFD_WRITEとFD_READを使うことで、シングルスレッドで実現可能でしょうか? よろしくお願い致します。

  • Winsockのsendto関数のタイムアウトについて

    はじめまして。。。 Winsockのsendto関数を使用してユニキャストでUDP送信 しているのですが、LAN切断時等送信先がない場合、 3秒くらいsendto関数の応答が帰ってこなくて困っています。 setsockoptの「SO_SNDTIMEO」で送信タイムアウトを 設定してみたのですが、状況は変わりませんでした。 もし、LAN切断時でもすぐに応答が帰ってくる方法が ございましたらご教示頂けないでしょうか? 環境 OS:Windows XP 言語:.NET 2003 C++

  • Winsock のUDP転送時の送信先サーバダウンの検出方法

    Winsock を使ってUDPを用いた通信プログラムを開発しておりますが、UDPでsendto()を用いて転送する際に、送信先のサーバがダウンしていても、sendto()の戻り値はエラーを返さないので、サーバがダウンしているかを検出する方法を教えてください。

  • ネットワークプログラミングにおいてsendto()ってブロックするの??

    C言語でネットワークプログラミング(ストリーミングのプログラムを作成しました) UDPを使用したプログラミングなのですが、サーバ側でデータを送るのが途中でいったん停止することがあるんです。数秒停止してまた送る。 もしクライアント側で何か処理が止まったときに、 ソケットのsendto(。。。。。)がブロックするのであればそのエラーもなっとくいくのですが。 sendtoってブロックするのでしょうか?? recvfrom()はソケットディスクリプタに応答があるまでブロックするのはわかるのですが・・・。sendtoはお構いなしに送信するんだったと思うのですが。 環境はサーバ、クライアントマシンともにlinux7.2です。

  • WinsockによるUDP通信にて

    WinsockでUDP通信を行うプログラムを作っているのですが、 原因不明の問題が発生していて困っています。 通信手順は以下のとおりです。 (1) クライアントからサーバへ要求パケット送信 (2) 要求パケットを受け取ったサーバは、クライアントへACKを送信 (3) サーバが要求に対する応答パケットをクライアントへ送信 (4) 応答パケットを受け取ったクライアントは、サーバへACKを送信 クライアント-サーバ間でやりとりするデータは最大で992バイト、 それ以上になる場合は、分割して送信します。 パケットの分割が発生しない場合は、(1)~(3)がパケットの損失もなく通信できるのですが、 パケットの分割が発生する場合には、2回目以降の(4)のパケットがクライアントに届きません。再現率は今のところ100%です。 クライアント側のselect関数でもソケットを検出しません。 たしかにUDPは信頼性が低いですが、パケット分割が発生しないパターンでは100%届くので、UDPの仕様とは関係ないような気がします。 原因がさっぱりわからないので、アドバイスをお願いいたします。 ちなみに、クライアント、サーバともに同一端末内にあります(双方がループバックアドレスに対してパケットを送信)が、 これはテスト段階だからであって、本来はそれぞれ別々の端末で動作します。

  • UDPのソケットプログラミング

    ソケットプログラミングでの質問です. 初心者です. UDPクライアントで sock = socket(PF_INET,SOCK_DGRAM,0) でUDPソケットを生成した後に bind()なしで,UDPサーバ宛にsendto() を行った場合, サーバのrecvfrom()でクライアントの IPアドレスとポート番号が受け取ることができると思いますが ここでのIPアドレスはクライアントのアドレスで, ポート番号は他のクライアントの他ソケットが使用していないポート番号 が受け取ることができると考えてよろしいですか? クライアントのsendto()で自動的にポート番号が割り当てられるが, クライアントが,どのポートから送信したのかを知る方法はないですか?

  • Winsockプログラミング Connectのエラーについて

    お世話になっております。 現在、Windowsソケットプログラム(winsock1.1)により、P2Pでの非同期のTCP通信プログラムを組んでます。 そこで、クライアントからサーバーへの同時接続のチェックをするために以下のような処理を行っています。 #関係ありそうな情報のみ載せます。足りなければご質問下さい。 OSはWindowsXP HomeEditionです。 なお、OSによる同時接続制限はBiotというツールにより20000というふうに設定しております。 ・クライアント 1.ソケット3000個用意 2.for文ループ処理によりソケット数分Connectを実行 ・サーバー 1.listenの同時接続最大数は20000に設定 毎回Connect実行時、大体2000回目辺りからエラーが出てきます。 その後、イベントが返って来た時のエラーチェックでも、WSAECONNREFUSED(10061)で「サーバーにより接続が拒否された。」というエラーが検出されます。 結局、接続成功は500~700回ぐらいでした。 この現象に対する対処法や解決法はないでしょうか? 現状では、全てのConnect要求を成功できるようにしたいと思っております。 子プロセスを作成するような方法は時間が無いので考えておりません。 9/18にも同じようなしておりますが、前より詳細を書いて再投稿いたしました。 以上、よろしくお願い致します。