• 締切済み

ソケットプログラミングで・・

簡単なソケットプログラムを作ろうとしておりまして、サイトで調べたりしておりましたところ、なんとか分かってきたのですが、ひとつどうしてもわからないことがありますので教えていただけますでしょうか。 ソケットから受信するメッセージの生成のところなんですが、 「WSAAsyncSelect(m_socket,m_hWnd,WM_USER_ASYNC_SELECT,FD_READ | FD_WRITE)」 で、2番目の引数「m_hWnd」がわかりません。 教えていただけないでしょうか?よろしくお願いします。

みんなの回答

  • 8oo
  • ベストアンサー率0% (0/1)
回答No.3

・・・あ、なんか、ちがう本書いてもた。 こっちだ。 「インターネットのためのWinsockプログラミング」

参考URL:
https://www.amazon.co.jp/exec/obidos/ASIN/4774103713/qid%3D1067694519/249-2656007-4265119
  • 8oo
  • ベストアンサー率0% (0/1)
回答No.2

接続イベント(FD_CONNECT)、受信イベント(FD_READ)、送信イベント(FD_WRITE)、 切断イベント(FD_CLOSE)の発生を伝えるWindowハンドルを指定します。 むか~しこの本を読みました。「WinSockによるWindowsネットワークプログラミング 」

参考URL:
http://www.amazon.co.jp/exec/obidos/ASIN/4756116094/ref%3Dnosim/2chbooks-22/249-2656007-4265119
  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.1

こちらの「III.非同期ソケット通信」のところが参考になりませんか? WSAAsyncSelect()で、例えば受信データありの場合にイベントとして通知する ウィンドウのハンドルをここに記述しておき、そのウィンドウのイベント ハンドラで受信処理を行なうようなプログラミングを可能にします。 http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

参考URL:
http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

関連するQ&A

  • 非同期関数とノンブロッキング関数について(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を使うことで、シングルスレッドで実現可能でしょうか? よろしくお願い致します。

  • ウィンドウのないActiveXコントロールへのメッセージ通知方法

     内部的にWinsock2を使用して別のサーバアプリケーションと通信を行うActiveXコントロールを作成しています。サーバからのデータ受信を非同期で行うため、WSAAsyncSelect()関数を使用して指定したウィンドウにWinsockからイベントメッセージ(メッセージIDはWM_USER+1を使用)を通知させます。 コントロールをウィンドウなしのアクティベーション使用で開発しているので、WSAAsyncSelect()のメッセージ通知対象ウィンドウがコントロール内にありません。 コンテナによりコントロール充てにメッセージを送ってくれるということなので、コンテナのウィンドウハンドルを取得し、WSAAsyncSelect()のメッセージ通知対象ウィンドウに設定しました。が、コントロールのOnMessageWindowless()にWM_USER+1のイベントは来ていないようです。 私が試したウィンドウハンドルは、次のコードで取得できるものです。 1. AfxGetMainWnd()->m_hWnd 2. CWnd::GetActiveWindow()->m_hWnd (CWndは使用するなとありましたが)  取得するウィンドウハンドルが間違っているのでしょうか?それとも、コンテナアプリケーションはWM_USERメッセージをコントロールに送ることができないのでしょうか?もしくは、コンテナにWM_USER+1のメッセージはコントロールへ、という設定をしてやる必要があるのでしょうか?  なお、なぜウィンドウありのコントロールにしないかと申しますと、ウィンドウありだとコンテナ(IEを想定)に乗った直後にウィンドウが生成されず、自分のウィンドウハンドルを取得しようとするとNULLが返ってしまうからです。ユーザがマウスで一度クリックすればOKなのですが・・・オブジェクト生成時に自動的にウィンドウを生成する方法がわかりませんでした。もしこちらが分かればウィンドウありで行くこともできますので、分かる方いらっしゃいましたらお願いいたします。

  • ソケットで通信できない

    Solaris + C で作成したプログラムAと、 PC上のVBで作成されたアプリBとの通信を行おうとしていま。 PC側のVBで、 Winsock.LocalPort = 3000 Winsock.Listen の処理があります。 Aではソケットの生成(socket)→接続(connest)→書込み(write)を行っていますが、すべて成功している模様です。 ・・が、VB側のWinsock_DataArrivaでブレークしていても、一向に受信する気配がありません。 VB及びソケットに関して、ほとんど知識がないので上記処理であっているかも分かっていません。 解決策をご存知の方がおられましたら、ご教授願いたく。

  • WinSockを用いたUDP送受信ソケットプログラミングについて

    こんにちは。 現在、VC++.NETでWinSockを用いたUDPソケットプログラミングを行っています。以下のようなプログラムを作りたいと思っているのですがうまく動作しません。 [概要] A:送信端末 B:受信端末 1.Aから文字列"send"をB端末へ送信。 2."send"を受信した受信端末Bは、A端末へ文字列"ok"を送信。 この1と2の動作を行わせたいと思っています。この場合、A,B端末は送信と受信を行う必要があります。 [問題点(うまくいかない点)] A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。 [気づいた点] ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。 送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?例えば、 s1 = socket(AF_INET, SOCK_DGRAM, 0);←送信に利用 s2 = socket(AF_INET, SOCK_DGRAM, 0);←受信に利用 よろしくお願いします。

  • Vista 非同期接続

    Vista と VC++2005 でソケット関連のソフトを作っています。  下のようなコードでは BEGIN_MESSAGE_MAP(SQMailDLDlg, CDialog) // Don't show process //{{AFX_MSG_MAP(MailRecDlg2) ON_MESSAGE(SM_ASYNC, HandleAsyncMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP() として、登録してある関数 HandleAsyncMsg() が呼び出されないのですが、 どこに原因があるのでしょうか? SendMessage(SM_ASYNC); とすれば、もちろん呼び出せます。 RetVal = getaddrinfo(gszServerName, Port, &Hints, &AddrInfo); if (RetVal != 0) { sprintf(outbuf3, "Cannot resolve address [%s] and port [%s], error %d: %s\n", Server, Port, RetVal, gai_strerror(RetVal)); WSACleanup(); return;// -1; } for (AI = AddrInfo; AI != NULL; AI = AI->ai_next) { ConnSocket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); if (ConnSocket == INVALID_SOCKET) { sprintf(outbuf3,"Error Opening socket, error %d: %s\n", WSAGetLastError(), DecodeError(WSAGetLastError())); continue; } if (WSAAsyncSelect(ConnSocket, *this, SM_ASYNC, FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT) == SOCKET_ERROR){ MessageBox("WSAAsyncSelect() failed","Error", MB_OK); closesocket(ConnSocket); ConnSocket = INVALID_SOCKET; continue; } if (connect(ConnSocket, AI->ai_addr, AI->ai_addrlen) == SOCKET_ERROR){ if(WSAGetLastError() != WSAEWOULDBLOCK){ closesocket(ConnSocket); ConnSocket = INVALID_SOCKET; continue; } break; } } if (AI == NULL) { sprintf(outbuf3, "Fatal error: unable to connect to the server.\n"); WSACleanup(); return;// -1; } よろしくお願いします。

  • winsockの非同期処理について

    winsockで双方向通信のため、非同期処理を行っているのですが、うまくいきません。 クライアント側で、WSAAsyncSelectの処理の後、Connectを呼んでいるのですが、Connectでエラーメッセージを返します。(エラーナンバー: 10035) サーバ側はaccept処理はうまくいっているのですが、accept後うまく処理を返していないためだと思うのですが... で質問は、 1.クライアント側、サーバ側にそれぞれ、WSAAsyncSelect を記載しても問題ないか? クライアント側はConnect前で宣言。 サーバ側はbind前で宣言しています。 2.エラー番号10035は非ブロッキングモードで処理されないためにおきています。 Connectで非ブロッキングモード処理がされていないためだと思うのですが、他に記述しないといけない関数があるのでしょうか? クライアント側: // 非同期処理 if(WSAAsyncSelect(client_s,this->m_hWnd, FM_TCPPROC, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR){ return FALSE; } // コネクト処理 memset(&client,0,sizeof(client)); client.sin_family = AF_INET; client.sin_addr.s_addr = inet_addr(IpAddress); client.sin_port = htons(PORT_NO); if(connect(client_s, (LPSOCKADDR)&client, sizeof(client)) == SOCKET_ERROR){ <-- ここでエラー long ErrNum = WSAGetLastError(); <-- ここでエラーNoがかえる。 return FALSE; }else{ NetFlg = true; } お分かりになる方教えてくださいませ。よろしくお願いします。

  • winsock2 非同期処理について

    教えてください。 winsockを使用して、ネットワーク間のアプリを作成しているのですが、 wndPorcが処理されないため困っています。 お分かりになる方教えてくださいませ。 送信側はメッセージを送っていますが、受信側のaccept処理が出来ません。(wndProcが呼ばれない) wndPorc関数って呼び出しって必要でしたか??? [環境] OS windows2000 Visual C++ 6.0 MFC [ソース] [.cpp内部] bool CSysCp02Dlg::NetWork_LogOn() { struct sockaddr_in server; // winsock初期処理 // ソケット作成 // 非同期処理 if(WSAAsyncSelect(server_s,this->m_hWnd,FM_TCPPROC,FD_ACCEPT|FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR){  return false; } // 構造体をクリア // 設定 // bind処理 // 受付開始(listen処理) return true; } LRESULT CALLBACK CSysCp02Dlg::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) <----ここの関数が処理されない。 { struct sockaddr_in client; int n; char Recv_Buffer[RECV_SIZE]; int nLength = sizeof(client); switch(message) { case FM_TCPPROC: switch( lParam ){ case FD_ACCEPT: client_s = accept(server_s, (struct sockaddr *)&client, &nLength); if(client_s == INVALID_SOCKET){ ErrNum = WSAGetLastError(); } break; } } return WndProc(hWnd, message, wParam, lParam); } 800文字以内に入りきらないため、略してあります。

  • Linux C言語 ソケット通信について

    C言語でソケット通信のプログラムを始めて作成しました。 受信時のデータ量が少ない場合は問題ないのですが、データ量が多くなると、 サーバーの受信が、出来たり、出来なかったりと不安定になります。 ログを確認しますと、パケットが勝手に分割されサーバーで受信した場合に、 おかしな動きになることがわかりました。 なぜそのようになるのか、また何がいけないのかわかりません。 どうぞご教授をお願いします。 FD_ZERO(&r_socket); FD_SET(sock, &r_socket); width = sock+1; *leng = 0; ef = TRUE; memset(&s,0x00,sizeof(s)); /* タイムアウト設定 */ time.tv_sec = 3; time.tv_usec = 0; while(1) { /* 受信待機 */ ret = select(width, &r_socket, NULL, NULL, &time) if ( ret < 0 ) { "受信待機エラー"表示 break; } if ( ret = 0 ) { "タイムアウトエラー"表示 break; } /* パケットを受信 */ if ( FD_ISSET(sock, &r_socket)) { memset(&rb,0x00,sizeof(rb)); read_len = read(sock, rb, sizeof(rb)); "受信した内容をログに出力" /* 割り込み中断エラーは継続し、その他エラーは終了する */ if ( read_len < 0 ) { if ( errno == EINTR ) { continue; } else { ef = FALSE; "受信エラー"表示 break; } } /* クライアントのソケットが閉じた場合は終了する */ if ( read_len == 0 ) { break; } /* データ送信要求を受信した場合は終了する */ if ( rb[read_len-1] == ACK ) { break; } /* 受信バッファーへ取り込み */ if ( rb[read_len-1] == ETX || rb[read_len-1] == ETB ) { len = read_len - 1; } else { len = read_len; } for (i = 0;i < len;i++) { if ( rb[i] != ETB ) { rsbuf[(*leng)++] = rb[i]; } } /* 最終データ時は終了する */ if ( rb[read_len-1] == ETX ) { break; } /* 最終データでない場合はデータ送信要求を送信する */ if ( rb[read_len-1] == ETB ) { sprintf(trxmsg,"%1c",ACK); ef = send_socket(sock, strlen(trxmsg), trxmsg); if ( ef != TRUE ) { break; } } } }

  • ソケットプログラミングに関する質問です

    ソケットプログラミングに関する質問です 最近ソケットプログラムに興味があり、勉強をしているのですが、 手始めにと下記の2つのプログラムをそのまま記述し http://cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoClient.c http://cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoServer.c TCPEchoClientプログラムから送信した英数字をTCPEchoServerがキャッチして TCPEchoClientの方へ送り返すプログラムを作ってみました。 その後、応用として手始めにTCPEchoClient側の送信元IPアドレスと送信した文字列 ex: 192.xxx.xxx.xx 'Hello World!' を送り返すプログラムを作成するために、 同じサイト内にあったHandleTCPClientを下記の通り 改造してみたのですが、引数に問題があるとエラーが出て先へ進めません。>< #include<stdio.h> #include<sys/socket.h> #include<unistd.h> #define RCVBUFSIZE 256 /* 受信バッファのサイズ */ void DieWithError(char *errorMessage); /* エラー処理関数 */ void HandleTCPClient(int clntSocket, int echoClntAddr) /* TCPクライアント関数処理 */ { char echoBuffer[RCVBUFSIZE]; /* エコー文字列のバッファ */ int recvMsgSize; /* 受信メッセージのサイズ */ struct clintIP echoClntAddr; /* クライアントのIPを取得 */ /* クライアントからの受信メッセージ */ if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE,clintIP,0)) < 0) DieWithError("recv() failed"); /* 受信した文字列を送信し、転送が終了していなければ次を受信する */ while (recvMsgSize > 0) /* 0は転送の終了を意味する */ { /* メッセージをクライアントにエコーバックする */ if (send(clntSocket,echoBuffer,recvMsgSize, 0) != recvMsgSize) DieWithError("send() failed"); /* 受信するデータが残っていないか確認する。 */ if ((recvMsgSize = recv(clntSocket, echoBuffer,RCVBUFSIZE, 0)) < 0) DieWithError("recv() failed"); } close(clntSocket); /* クライアントソケットをクローズする */ } 単純にTCPEchoServerの echoClntAddr.sin_addrという箇所が送信元のIPを 引っ張ってきてるからHandleTCPClientの方へ 関数をstructで引っ張ってくればいいと思ったのですが、そういうわけでもないのです。

  • VC6.0ソケット通信プログラムについて

    お世話になります。 VC6.0でソケット通信の社内の既存のプログラムを改善しております。 クライアントより、サーバにソケットで大量に電文を送信した時に、サーバ側の処理が重くなってしまいます。 NETSTATコマンドで確認したところ、 サーバ側では、CLOSE_WAITが大量に出力されており クライアント側では、FIN_WAIT_2が大量に出力されます。 クライアント側のFIN_WAIT_2は、時間が経つと消えるのですが、サーバ側のCLOSE_WAITは残ってしまっております。 サーバ側のEXEを再起動すると、CLOSE_WAITは消えます。 サーバ側のソケットの受信後の処理に問題があるのではと考えておりますが、何処が問題なのかわからない状態です。 コードを以下に記述致します。 WINAPI K010cListener{ /*Winsock初期化*/ WSAStartup(wVersionRequested,&wsaData); /*SOCKET作成*/ fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) /*ポートの設定*/ addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_family = AF_INET; addr.sin_port = htons(usPortNo); addrlen = sizeof(addr); /*BIND*/ bind(fd,(struct sockaddr*)&addr,addrlen) /*LISTEN*/ listen(fd,0) while(1){ /*ACCEPT*/ fd2 = accept(fd,(struct sockaddr*)&addr,&addrlen) //データ受信 waitReceiveThread(fd2, &rcv_msg); //DBオープン ConnectDB() //DB登録 AddTable(&rcv_msg) //DBクローズ CloseDB() } /*Winsock終了*/ WSACleanup(); } void waitReceiveThread(SOCKET fd, SockRcvMsg *rcv_msg) { while (1) { /*データ受信待ち*/ rcvSize = recv(fd,rcvBuf,sizeof(rcvBuf),0); if (rcvSize <= 0) { continue; } else { /* 返信電文の準備 */ memset(sndBuf,0x20,sizeof(sndBuf)); memcpy(sndBuf ,"RCMORDER00004800000000",22); /* 返信電文の送信 */ send(fd,(char*)sndBuf,sizeof(sndBuf),0); /* バッファの初期化 */ bufsize=0; memset(buf,'\0',sizeof(buf)); break; /*ループを抜ける*/ } } } 恐れ入りますが、ご教授いただければ幸いです。 宜しくお願い申し上げます。