• ベストアンサー

TCP/IP通信型プログラムです。 サーバのポート番号をクライアントが

TCP/IP通信型プログラムです。 サーバのポート番号をクライアントが取得するプログラムで、 while(1) { saddr.sin_port=htons(port); port++; fprintf(stdout, "%d\n", port); } のようなのをプログラムのどこに入れれば よいのでしょうか?

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

while((ntohs(saddr.sin_port) <= 0xffff) && (connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)) {  saddr.sin_port = htons((ntohs(saddr.sin_port) + 1)); } こんなところでしょうか。 whileループに入る前に、スキャンするポートの開始値をsaddr.sin_portに設定しておく必要があります。 # 勿論、それ以外のメンバ変数も適切に設定してある必要があります。 65535番ポートまで接続を試行し、『最初に接続できた』ところでループから抜けるでしょう。 が…… >サーバ自身がポート番号をランダムに変更する設定となっているからです。 というのは設計ミスとしか思えませんが。 上記の方法では接続できるまでポート番号を変えながら試行しますけど、connect()がエラー返却するのに時間が掛かる場合、全ポートの試行が終わるまでにどれだけ掛かるやら…。 接続できたとしても、#2さんが指摘しているとおりソレが目的のサーバプログラムが待ち受けしているポートかは不明です。 例えば同じマシンでWebサーバが動作していて80番で待ち受け中に、目的のサーバが7000番とかで待っていた場合、先に接続するのはWebサーバの方です。

pikayuki
質問者

お礼

ありがとうございます。これでやってみます。

その他の回答 (2)

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

ANo.1のコードからするとポートスキャンしてサーバが待っているポートを探すのでしょうか。接続できるポートを見つけてもどんなサーバが待っているか判定できないので良い方法とは言えません。 実用的にはサーバを立ち上げて待機ポートが決まったときに何らかの手段で通知するしかありませんが、一般的な方法はありません。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

なぜそのようなことをする必要があるのか、疑問ですが… saddr.sin_port構造体に設定する前…ということで、socket()でソケットを生成する前…ではないでしょうか。 普通、サーバは特定のポートで待ち受けしているわけで、クライアントがサーバ側で待ち受けているポートを「探す」ということはやらないかと思いますが…。 ちなみに、掲示されている例では、当たり前ですがサーバには接続していません。

pikayuki
質問者

補足

サーバ自身がポート番号をランダムに変更する設定となっているからです。聞いた話では、 if(connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connect"); exit(1); } ここのところをいじればいいそうなのですが・・・。

関連するQ&A

  • TCP/IP通信型電話番号検索プログラムを作りたいです。

    TCP/IP通信型電話番号検索プログラムを作りたいです。 クライアントは以下のようで大丈夫みたいなのですが、サーバの方を修正しなければなりません。 この質問で「TCP/IP通信型大文字・小文字変換プログラム」を発見しました。 サーバー側プログラム #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SOCK_NAME "./socket" int main() { int i; int fd1, fd2; struct sockaddr_in saddr; struct sockaddr_in caddr; int len; int ret; char buf[1024]; if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=INADDR_ANY; saddr.sin_port=htons(1357); unlink(SOCK_NAME); if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(1); } if(listen(fd1,5) < 0 ) { perror("listen"); exit(1); } while(1){ len = sizeof(caddr); if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){ perror("accept"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", fd2); while((ret = read(fd2, buf, 1024)) > 0 ){ fprintf(stderr, "read: &s\n", buf); for(i=0; i<ret; i++) if(islower(buf[i])) buf[i] = toupper(buf[i]); if(isupper(buf[i])) buf[i] = tolower(buf[i]); fprintf(stderr, "write: %s\n", buf); write(fd2, buf, 1024); } close(fd2); } close(fd1); return 0; } 先生によると、クライアントは同じもので良いそうです。 誰か、助けて下さい。

  • TCP/IP通信型大文字・小文字変換プログラム

    TCP/IP通信型大文字・小文字変換プログラムを作りたいです。 しかし、うまく2つのプログラムが接続されません。 恐らく、IPアドレスやホスト名の問題だと思います。 超初心者でそこのところをあまり理解していません。 どなたかプログラムの補足をお願いします。 概要は ・クライアント キーボードから文字列を入力し、サーバーに送信。 サーバーから送信された文字列を画面に出力。 ・サーバー クライアントから送信された文字列に対し、 大文字は小文字に、小文字は大文字に変換して返す。 クライアント側プログラム #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define SOCK_NAME "./socket" int main() { struct sockaddr_in saddr; int soc; char buf[1024]; if ( (soc =socket(AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=inet_addr("192.168.1.1"); saddr.sin_port=htons(1357); if(connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connect"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", soc); while(fgets(buf, 1024, stdin)){ if(buf[strlen(buf) -1] == "\n") buf[strlen(buf) -1] = "\0"; write(soc, buf, 1024); read(soc, buf, 1024); fprintf(stdout, "%s\n", buf); } close(soc); return 0; } サーバー側プログラム #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SOCK_NAME "./socket" int main() { int i; int fd1, fd2; struct sockaddr_in saddr; struct sockaddr_in caddr; int len; int ret; char buf[1024]; if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=INADDR_ANY; saddr.sin_port=htons(1357); unlink(SOCK_NAME); if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(1); } if(listen(fd1,5) < 0 ) { perror("listen"); exit(1); } while(1){ len = sizeof(caddr); if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){ perror("accept"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", fd2); while((ret = read(fd2, buf, 1024)) > 0 ){ fprintf(stderr, "read: &s\n", buf); for(i=0; i<ret; i++) if(islower(buf[i])) buf[i] = toupper(buf[i]); if(isupper(buf[i])) buf[i] = tolower(buf[i]); fprintf(stderr, "write: %s\n", buf); write(fd2, buf, 1024); } close(fd2); } close(fd1); return 0; }

  • TCP/IP通信に関する質問です。

    下記の3つのLinuxPCを使って、TCP/IPによるソケット通信のシステムを作成しました。 PC1: IP:192.168.0.1 Port: 20000 TCPサーバ PC2: IP:192.168.0.2 Port: 20000 TCPサーバ PC3: IP:192.168.0.3 Port:ランダム(クライアントなので) TCPクライアント PC3をクライアントとして、同じポート番号を持つアプリが動いている PC1とPC2に繋いで通信をする形です。 このシステムは問題なく動きました。 しかし、続いてPC1とPC2を一つのPCに(ハードウェアとして)まとめたくなったときに、 下記の条件があったとき、どのようにすれば良いでしょうか? 1. PC3のソフトウェアは一行も変更しない 2.りPC1とPC2が同一のハードウェアになっても、それぞれのソケットに流れるデータは変わらない 一台のコンピュータにおいて、一つのNICに複数のIPをふることはできましたが、 同じポート番号のソケットを作成するのはできないと思っています。 今のところ、一台のコンピュータで仮想マシンを二台立ち上げる方法を考えていますが、 それ以外に上手い方法はあるでしょうか? 非常に困っているため、ご回答よろしくお願いします。

  • ゲームの通信プログラムについてなんですが

    ボードゲームで対戦用にとTCP通信プログラムを導入したいのですがどうにもうまくいきません。 ゲームのところでつながっているにはつながっているんですが無限ループのように通信しているようなんです。 VisualStudio2010とwinsocketを使っております。 サーバーのプログラムはこうです。 void COMMU::SERWSA() { port = 6543; //WinSock初期化 rtn = WSAStartup( MAKEWORD(2,2), &wsaData); } void COMMU::SERSOCK() { listen_s = socket( AF_INET, SOCK_STREAM, 0); if(listen_s < 0)     { WSACleanup(); return; } //0で初期化 memset(&saddr, 0, sizeof(SOCKADDR_IN)); saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = INADDR_ANY; if(bind(listen_s, (struct sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)     { closesocket(listen_s); WSACleanup(); return; } } void COMMU::SERLIS() { //クライアントからの接続待ち状態にする if(listen(listen_s, 0) == SOCKET_ERROR) { closesocket(listen_s); WSACleanup(); return; } fromlen = (int)sizeof(from); s = accept(listen_s, (SOCKADDR *)&from, &fromlen); if(s == INVALID_SOCKET)     { closesocket(listen_s); WSACleanup(); return; }else{ inet_ntoa(from.sin_addr); } //リスンソケットはもう不要 closesocket(listen_s); MessageBox(NULL,"繋がった","読み込みエラー", MB_OK |MB_ICONERROR); } COMMU::~COMMU() { if(shutdown(s, SD_BOTH) != 0){ perror("シャットダウンに失敗しました\n"); } //ソケットのクローズ closesocket(s); //ソケットのリソース解放 rtn = WSACleanup(); if(rtn == SOCKET_ERROR){ fprintf(stderr, "WSACleanup失敗\n"); return; } printf("WSACleanup成功\n"); printf("サーバ終了\n"); } 続いてクライアントです。 void Client::CLWSA() { //ポート番号の入力 port = 6543; //数値に変換 //WinSock初期化 rtn = WSAStartup( MAKEWORD(2,2),//上位と下位を指定してWORDデータを返すマクロ &wsaData); } void Client::CLSOCK() { //ソケットを開く s = socket( AF_INET, //アドレスファミリ SOCK_STREAM, //TCP(接続型通信)で通信 0); //プロトコル(0:WinSockが自動的に判断) if(s < 0){ //perror("ソケットをオープンできません\n"); WSACleanup(); return; } //ホスト名からホスト情報を取得 lpHost = gethostbyname("PC○○"); if(lpHost == NULL)     { addr = inet_addr(szServer); //ネットワークアドレスからホスト情報を取得 lpHost = gethostbyaddr((char*)&addr,4,AF_INET); } if(lpHost == NULL)    { printf("ホスト情報取得エラー\n"); closesocket(s); WSACleanup(); getchar(); return; } } void Client::CLCONNE() { //0で初期化 memset(&saddr, 0, sizeof(SOCKADDR_IN)); saddr.sin_family = lpHost->h_addrtype; //ホストのアドレスファミリ saddr.sin_port = htons(port); saddr.sin_addr.s_addr = *((u_long *)lpHost->h_addr); //接続要求する if(connect(s, (SOCKADDR *)&saddr, sizeof(saddr)) == SOCKET_ERROR){ printf("connectエラー\n"); closesocket(s); WSACleanup(); getchar(); return; }else{ MessageBox(NULL,"つながりました","読み込みエラー", MB_OK |MB_ICONERROR); } } Client::~Client() { if(shutdown(s, SD_BOTH) != 0){ perror("シャットダウンに失敗しました\n"); } //ソケットのクローズ closesocket(s); //ソケットのリソース解放 rtn = WSACleanup(); if(rtn == SOCKET_ERROR){ fprintf(stderr, "WSACleanup失敗\n"); return; } printf("WSACleanup成功\n"); printf("クライアント終了\n"); } です。 わかりにくいかと思いますがかなり困ってます・・・ 回答よろしくお願いします。

  • TCP/IP通信型プログラムです。作成するのはクライアントです。たとえ

    TCP/IP通信型プログラムです。作成するのはクライアントです。たとえば、サーバから入力を求められ、それが正しくあれば、次の状態へ。正しくなければ、状態を遷移させなかったり。そして、状態が遷移したということをサーバに伝えなければなりません。自分としては、条件式などを利用しようかと思っているのですが・・・。(状態遷移図の作成ではありません。) ほんのわずかなヒントでもいいので、お助け願います。

  • TCP/IP通信型プログラムです。作成するのはクライアントです。たとえ

    TCP/IP通信型プログラムです。作成するのはクライアントです。たとえば、サーバから入力を求められ、それが正しくあれば、次の状態へ。正しくなければ、状態を遷移させなかったり。そして、状態が遷移したということをサーバに伝えなければなりません。自分としては、条件式などを利用しようかと思っているのですが・・・。(状態遷移図の作成ではありません。) ほんのわずかなヒントでもいいので、お助け願います。

  • C#とTCP/IPを利用したサーバープログラム(複数クライアント対応)

    VC#とTCP/IPを利用したサーバープログラムを制作しています。 サーバーとクライアントの1対1での通信には成功したのですが、1つのサーバーで複数のクライアントと通信する方法がわかりません。 同じポート番号を利用できるのでしょうか。ただ単にTcpClientの配列を作ればいいのでしょうか。やはりクライアントの数だけスレッドを作らないといけないのでしょうか。 環境はWindowsVistaでMicrosoft Visual C# 2008 Express Editionを使用しています。 詳しい方がいましたらぜひ具体的なC#でのコード等を教えてください。 よろしくお願いいたします。

  • VC++でのTCP/IPサンプルプログラムでClient.exeを複数起動すると通信できない

    CQ出版Interface誌12月号のVC++でのTCP/IPサンプルプログラム http://www.cqpub.co.jp/interface/download/contents.htm 第1章 C言語で書くシンプルなWebサーバの製作 このプログラムのserver.exeを起動させて、Client.exeを複数起動させてみたのですが、Client.exeの片方が通信できるのですが、網片方のClient.exeはサーバとの通信ができていないようで、通信できていた方のClient.exeを停止させると通信ができるようになるようです。 このプログラムではClient.exeが複数あった場合に同時に通信を行わせると言うことはできないのでしょうか?

  • IP/TCPの通信規格がわか

    現在、遠隔操縦ロボットの製作で通信システムをクライアントサーバー方式を使用しています。 IP/TCPを使っていましたが、質疑応答で、IP/TCPの通信規格は何かと言われましたが答えることができませんでした。どなたか教えてくれませんか?

  • TCP/IPを使用したサーバークライアントに関して

    TCP/IPを使用したサーバー、クライアントの考え方に関して、教えてほしいのですが? 今、TCP/IPを使用して、PCから装置のLEDをON/OFFしたり、 装置からはADのデータをPCに送る場合。 PCをクライアント、装置をサーバとした時、装置のIPアドレスとPC側のポート番号を 決めて、予め装置のファームウェアに焼き付けておけば、PCのアプリ側では、 装置側のIPが分かっているので、装置からの接続要求を受付けできますが、 逆にPCをサーバ、装置をクライアントとした時、装置側では、PCのIPアドレス(DHCPに より自動的に割り当てられる場合)が分からなければ、 1.装置側では、PCへの接続が出来ないと思うのですが、如何でしょう、 他に手だてがありますか? 2. この様な場合、PCをクライアント、装置をサーバとして、組むのが一般的なのでしょうか? 条件としては、装置側にPCのIPアドレスは入力できないものとし、また、PCのIPアドレスはDHCPで自動的に割り当てられるものとする。 詳しい方、ご教授お願いします。