CのWindowsアプリケーションとしてソケット通信のプログラムを作って
います。
現在、1対1の社内パソコン同士で、一方のホスト名を手入力させることで
ソケット通信が可能な状態です。
-------------------------------------------------------------
クライアント側:サーバー側のホスト名を手入力で指定して接続
↑
|接続
↓
サーバー側:接続待ち
-------------------------------------------------------------
これを手入力の必要なく、自動で接続が行なわれるようにしたいです。
やり方を教えて頂けないでしょうか?
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
30分ほどで簡単にコードを書いてみました。
なので、申し訳ありませんが動作未確認です。あくまで参考程度にご覧いただき、使用している関数の意味等についてはご自分でお調べいただければ幸いです。また、命令受信後にはホスト名を文字列として返していますが、当然ながらIPアドレス4バイトを返信してもOKです。ポイントは2点。(1) UDPソケット生成時には「SOCK_DGRAM」を使用する(TCPでは「SOCK_STREAM」)、(2) ブロードキャストアドレスとして"255.255.255.255"を指定する
なお、下記のプログラムの構造でそのまま実行しようとした場合、select実行時に何らかのパケットを受信するまで確実にプログラムが停止します。正常動作するアプリケーションを作成されるのであれば、「UDP受信」「UDP送信」「TCP受信」「TCP送信」の各スレッドを生成する必要があります。
●参考サイト
Geekなぺーじ : UDPでブロードキャストを使う
http://www.geekpage.jp/programming/winsock/broad …
ソケットプログラミング
http://www.katto.comm.waseda.ac.jp/~katto/Class/ …
●仕様
・任意PCより、LAN内のPCに対してアプリケーションの有無を検索する側を「検索元側」と呼称する
・予めLAN内で起動しており、検索される側を「被検索側」と呼称する
・検索元側はUDPにより1バイトのホスト名要求命令を送信する
・ホスト名要求命令を受信した被検索側は、ホスト名を文字列として送信する
・通信ポート番号は12345とする
・被検索側のホスト名は"example.com"とする
// ========== 検索元側・被検索側共通マクロ ==========
#define REQUEST_HOST 0x01 // ホスト名要求命令
#define PORT_NUM 12345 // ポート番号
// ========== 検索元側ここから ==========
#include <winsock2.h> // Windows用なのでWinsock2をインクルード
// ----- 0.前準備 -----
// Winsock2初期化
WSADATA data;
WSAStartup (MAKEWORD (2,0), &data));
// ----- 1. UDPパケット送信 -----
// ソケット生成
SOCKET socUDP;
socUDP = socket (AF_INET, SOCK_DGRAM, 0);
// sockaddr_in構造体セット
struct sockaddr_in addrUDP;
memset (&addrUDP, 0, sizeof (addrUDP));
addrUDP.sin_port = htons (PORT_NUM); // ポート番号設定
addrUDP.sin_family = AF_INET;
addrUDP.sin_addr.s_addr = inet_addr ("255.255.255.255"); // ブロードキャストアドレス指定
// パケット送信
char szBuf[] = {REQUEST_HOST};
sendto (socUDP, szBuf, 1, 0, &addrUDP, sizeof (addrUDP));
// 送信完了
closesocket (socUDP);
// ----- 2. UDPパケット受信 -----
// ソケット生成
socUDP = socket (AF_INET, SOCK_DGRAM, 0);
// sockaddr_in構造体セット
memset (&addrUDP, 0, sizeof (addrUDP));
addrUDP.sin_port = htons (PORT_NUM); // ポート番号設定
addrUDP.sin_family = AF_INET;
addrUDP.sin_addr.s_addr = htonl (INADDR_ANY);
// バインド
int nStatus = bind (socUDP, (struct sockaddr_in *) &addrUDP, sizeof (addrUDP));
// selectで受信待機
fd_set fds;
FD_ZERO (&fds); // fd_set初期化
FD_SET (socUDP, &fds); // selectで待つ読み込みソケットを登録
select (socUDP +1, &fds, NULL, NULL, NULL); // UDPパケットを受信するまで待機
// 読み込み可能データ受信
char szBuf[256];
if (FD_ISSET (socUDP, &fds)) {
// ソケットからデータを受信
memset (szBuf, 0, 256);
int nRecv = recv (socUDP, szBuf, 256, 0);
// 受信データを表示(ホスト名のはず)
printf ("%s", szBuf);
}
// 受信完了
closesocket (socUDP);
// ここにTCP通信処理
// ----- 3.終了処理 -----
WSACleanup ( );
// ========== 被検索側ここから ==========
#include <winsock2.h> // Windows用なのでWinsock2をインクルード
// ----- 0.前準備 -----
// Winsock2初期化
WSADATA data;
WSAStartup (MAKEWORD (2,0), &data));
// ----- 1 UDPパケット受信 -----
// ソケット生成
SOCKET socUDP;
socUDP = socket (AF_INET, SOCK_DGRAM, 0);
// sockaddr_in構造体セット
struct sockaddr_in addrUDP;
memset (&addrUDP, 0, sizeof (addrUDP));
addrUDP.sin_port = htons (PORT_NUM); // ポート番号設定
addrUDP.sin_family = AF_INET;
addrUDP.sin_addr.s_addr = htonl (INADDR_ANY);
// バインド
int nStatus = bind (socUDP, (struct sockaddr_in *) &addrUDP, sizeof (addrUDP));
// selectで受信待機
fd_set fds;
FD_ZERO (&fds); // fd_set初期化
FD_SET (socUDP, &fds); // selectで待つ読み込みソケットを登録
select (socUDP +1, &fds, NULL, NULL, NULL); // UDPパケットを受信するまで待機
// 読み込み可能データ受信
char szBuf[256];
if (FD_ISSET (socUDP, &fds)) {
// ソケットからデータを受信
memset (szBuf, 0, 256);
int nRecv = recv (socUDP, szBuf, 256, 0);
// ホスト名要求命令でない場合はエラー終了
if (szBuf[0] != REQUEST_HOST) {
closesocket (socUDP);
return 1;
}
}
// 受信完了
closesocket (socUDP);
// ----- 2. UDPパケット送信 -----
// ソケット生成
socUDP = socket (AF_INET, SOCK_DGRAM, 0);
// sockaddr_in構造体セット
memset (&addrUDP, 0, sizeof (addrUDP));
addrUDP.sin_port = htons (PORT_NUM); // ポート番号設定
addrUDP.sin_family = AF_INET;
addrUDP.sin_addr.s_addr = inet_addr ("255.255.255.255"); // ブロードキャストアドレス指定
// パケット送信
char szBuf[256];
strcpy (szBuf, "example.com");// ホスト名設定
sendto (socUDP, szBuf, strlen (szBuf) + 1, 0, &addrUDP, sizeof (addrUDP));
// 送信完了
closesocket (socUDP);
// ここにTCP通信処理
// ----- 3.終了処理 -----
WSACleanup ( );
No.2
- 回答日時:
サーバー側が起動している事を条件として、以下の手順でしょうか。
1.ホスト名要求
クライアント起動時にLAN内に「ホスト名要求命令」を
UDPブロードキャストにて送信
2.ホスト名返信
サーバがUDPパケットを受信、解析し、「ホスト名要求命令」である場合には
サーバのホスト名を同じくUDPにて返信
3.ホスト名受信
クライアントがUDPパケットを受信、解析し、サーバのホスト名を取得
4.TCPコネクション作成
3にて取得したホスト名によりクライアント側にてTCPソケットを生成、
connectする。以降の通信はTCPにより行う
もう少し賢いやり方(1でクライアント側ホスト名をサーバに通知し、2の段階でサーバ側からクライアント側にTCPで接続、など)があるかもしれませんが、だいたいこんな感じで出来るかと思います。
なお、各命令はクライアントとサーバであらかじめ取り決める命令で、同様にポート番号もあらかじめ相互に決定済みである必要があります。
この回答への補足
ご回答ありがとうございます。
もしよろしければ
1~3までの手順のソース(C言語)を載せて頂けたら大変助かります。
いろいろ検索してみたのですが、どうにもわからなくて……
どうかよろしくお願い致します。
No.1
- 回答日時:
自動とは、どういった動きを期待していますか?
例えば、サーバー端末が1台のみで固定であれば、あらかじめ、そのホスト名を保持しておけば言い訳ですし、逆に複数のサーバー端末が存在する場合、複数のサーバーのうち、どれに接続すべきかという条件がなければ、一意のサーバーに接続することは難しいと思います。
この回答への補足
ご回答ありがとうございます。
説明不足で申し訳ありません。
同じLANで繋がっている複数のパソコン同士が、ユーザーによる手入力を必要とせず、プログラムから自動的にLANに接続されているパソコン全てのホスト名を取得および表示できるようなふうにしたいです。
「IP Messenger」http://www.ipmsg.org/
というフリーソフトが正にそうなっておりまして、exeファイルを起動させるだけで、同じLAN内のパソコンであれば勝手にLAN内のパソコンのホスト名を取得して表示してくれます。
(こちらのソフトはソースが公開されていますが、解析しようと試みたところまるで歯が立ちませんでした)
こういった機能はどのようにしたら実現できるのでしょうか?
ご指導頂けたら幸いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Windows 10 インストールしたてのVirtualBoxの仮想マシンにDHCPで割り振られるIPアドレスにつきまして 1 2023/05/03 14:46
- ネットワーク 自作のサーバーPCが自宅内のネットワークに接続できない 3 2023/01/24 16:58
- その他(開発・運用・管理) Windowsバッチファイルでリモートデスクトップを自動ログインするが確認画面が出る対処方法 1 2022/12/19 15:48
- デスクトップパソコン 古ーいパソコン/Atheros AR2181 PCIe Gigabit LAN コントローラー 7 2022/09/07 12:58
- サーバー ネットワークの構成に困っています 3 2023/07/05 11:55
- ドメイン・サーバー・クラウドサービス FileZillaを使用してwpXサーバーに接続できない 2 2022/03/29 21:02
- ルーター・ネットワーク機器 家庭内LAN 4 2023/06/29 12:13
- サーバー Googleドライブなどを使わずにテザリングAndroidでWindowsとファイル共有 1 2023/02/19 13:14
- 中古パソコン USBキーボードを外すと、起動できなくなる 2 2023/03/25 14:57
- UNIX・Linux リナックスのリモート接続の際に使う sshコマンドについて 1 2022/11/21 19:46
このQ&Aを見た人はこんなQ&Aも見ています
-
新NISA制度は今までと何が変わる?非課税枠の拡大や投資対象の変更などを解説!
少額から投資を行う人のための非課税制度であるNISAが、2024年に改正される。おすすめの銘柄や投資額の目安について教えてもらった。
-
LAN内接続マシン数及びIP、マシン名の表示について
Visual Basic(VBA)
-
相手のIPアドレスを取得する方法
C言語・C++・C#
-
ソケットでクライアントのipアドレスを取得できるそうですが・・・
C言語・C++・C#
-
-
4
IPアドレスを検査する関数
C言語・C++・C#
-
5
IPアドレスを変更するプログラム
C言語・C++・C#
-
6
ネットワーク切断を検出するには?
C言語・C++・C#
-
7
C言語でネットワーク範囲のIPアドレスを取得
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ソケットのrecvの戻り値が0
-
TCP/IP通信時のサーバーからの受信
-
Winsockを使わずにVBでSocketを...
-
エクセル VBA でのCOMポート...
-
VB6のwinsockでconnectできない
-
VB6‥ソケットについて
-
Socket通信の0バイト受信について
-
UDP通信におけるbind関数について
-
WinSockでの通信プログラムがう...
-
winsockを使った通信での同時接...
-
MFCソケットについて
-
recv関数でフリーズしてしまう
-
異なる言語間でのソケット通信...
-
WinSockでのソケット通信
-
VC++でのソケット通信について
-
Javaプログラム同士のプロセス...
-
Winsockで接続待ちタイムアウト...
-
C#とTCP/IPを利用したサーバー...
-
TCP/IP通信(ソケット通信)に...
-
名前付きパイプの通信ポートに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
エクセル VBA でのCOMポート...
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
UdpClient 送信元のIPアドレ...
-
Winsockで接続待ちタイムアウト...
-
recv関数でフリーズしてしまう
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
Socket通信の0バイト受信について
-
ソケット通信 同じポート番号...
-
相手のIPアドレスを取得する方法
-
ソケットでクライアントのipア...
-
VB6のwinsockでconnectできない
-
Connectエラーが出てしまう・・...
-
ソケット通信の送受信遅延-02 ...
-
同じLAN内パソコンのIPアドレス...
-
WinSockでの通信プログラムがう...
-
UDPのソケットプログラミング
-
非ブロッキングソケットのrecv...
おすすめ情報