• 締切済み

Socket通信を待ち受け状態にするには

Androidアプリの開発でJavaのSocketを使って通信しようと考えています。 現在、ソースが手元にない状態なのですが、 SocketDebuggerをサーバとして、クライアントプログラムを書きました。 流れは、指定のポート、アドレスに接続して入力された文字列をサーバが受け取り、 メッセージを返信するものです。 なのですが、サーバ側から再度メッセージを送信したときに今度はクライアント側で 受け取りそれにまた返信する…ということをやりたいのですが、今の状況ではサーバからのメッセージを受け取ることが出来ません。 プログラムは以下のサイトを参考にして少し書き換えました。 http://team-pag.interprism.co.jp/member/okazawa/blog/?p=687 今のままだとクライアント側から送信するとそのまま接続が終了してしまうのですが、 たとえば「exit」を受け取ったら接続をやめる、、それまではサーバからのメッセージも受け取れる状態にする…というようにやりたいです。 ご教授お願いします!!

みんなの回答

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

技術的にはServerSocketを作り、bind、acceptで ソケット通信のサーバ側は処理します。 しかし、その前にプロトコルはどうなっていますか? サーバからデータが無秩序に送られてくるような プロトコルなんでしょうか? よくあるFTPなどは1要求1応答と決まっています。 大量のデータを受け渡す時はデータ用ソケットを別に 作って処理します。 この時はクライアント側がサーバのように振舞いますが、 相手(サーバ)に自分(クライアント)のアドレスを知らせる 必要があるので、accept前にアドレスを通知する要求を サーバに送るようになっています。 無秩序な送受信(TELNETはこのタイプ)なら、ソケットを 閉じなければよいだけの話です。 その他に、受信は受身で対応しなければならない性格 から、本体とは別のスレッドで処理するのが普通です。 また、通信は相手と通信経路の問題があるので、何時 切断されるか分かりません。そういった対処も考えて おかなければなりません。 経験的に見てマルチスレッドでないと実用的なものは 難しいでしょう。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • socketプログラミングについて

    C++でsocketの練習のためにソケットを開き、文字列の送信を行うだけのサーバクライアントプログラムを作成したのですが、どうも上手く動作してくれません。 クライアント→サーバへ文字列を送信する前に、 1.サーバがソケットを開き、9999ポートでアクセスを待つ 2.クライアントがソケットを作成し、サーバの9999ポートにアクセスする 3.クライアントが文字列をサーバへ送信し、サーバが文字列を表示 ということをしたいのですが、2の部分でつまずいています。 プログラムをネットワークに接続されているコンピュータ上で実行すると動作するのですが、(client 192.168.15.17 9999)単独でサーバ・クライアントを起動させ、localhost当てに接続(client localhost 9999)しようとしても「No route to host」と表示されて、接続すら出来ません。 ためしにサーバを起動させている状態で「telnet localhost 9999」とするとどうやらサーバに接続されているようです。 localhostでやる場合は特別なソケット操作が必要になるのでしょうか?

  • Socket通信での通信異常について

    JavaでSocket通信している状態で、物理LANを抜いたりして通信異常状態を起こしても、すぐには通信異常と検知できないようで、一定期間してからSocketExceptionなどを検知します。 現在、クライアントとサーバで常に受信し続け、各々で1秒毎にSocketでメッセージを相互に送っております。 その間で物理LANを抜いても、一定期間は送信しつづけるように見え(実際受信はされていない)、 一定時間を超えると、上記のようにSocketExceptionで例外検知します。 上記のようにSocket通信で通信異常状態の場合には即検知することは無理なのでしょうか?

    • ベストアンサー
    • Java
  • Linuxのsocket接続でacceptできない

    Ubuntu 10.10 + gcc4.4 + eclipse で C言語プログラミングをしています。 ソケットを使用したプログラムを試していたのですが、思うように動作しません。 作成したプログラムは以下のようなものです。 ・ローカルマシン上で、サーバプログラム、クライアントプログラムを用意する ・サーバ側はソケット作成後、クライアントが接続するまで listen する ・クライアントはサーバに接続したら、接続した旨を表示する という初歩的なものです。 問題は、サーバ側が accept したときに戻り値 -1 を返却して終了してしまうことです。 以下が作成したソースです。 ■■■▼ サーバ側ここから ▼■■■ #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int sockfd; struct sockaddr_un srv; socklen_t socklen; /* ソケット名をコマンド入力で受け取る */ if(argc != 2) { puts("USAGE: mksock <filename>"); exit(EXIT_FAILURE); } /* ソケット作成 */ if((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ exit(EXIT_FAILURE); } /* srv 初期化 */ memset(&srv, 0, sizeof(srv)); srv.sun_family = AF_UNIX; strncpy(srv.sun_path, argv[1], sizeof(srv.sun_path)); /* バインド */ if((bind(sockfd, (struct sockaddr *)&srv, SUN_LEN(&srv))) < 0){ exit(EXIT_FAILURE); } /* クライアントからの接続待ち */ if((listen(sockfd, 5)) < 0) { exit(EXIT_FAILURE); } printf("socket available: %s, sockfd=%d\n", srv.sun_path, sockfd); /* 接続がある限りくりかえす */ int sockResult; while(1) { sockResult = accept(sockfd, (struct sockaddr *)&srv, &socklen); printf("sockResult = %d, sun_path=%s\n", sockResult, srv.sun_path); if (sockResult < 0) break; puts("new connection granted"); } puts("mksock end"); exit(EXIT_SUCCESS); } ■■■▲ サーバ側ここまで ▲■■■ ●●●▼ クライアント側ここから ▼●●● #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int sockfd; struct sockaddr_un cli; socklen_t socklen; /* ソケット名をコマンド入力で受け取る */ if(argc != 2) { puts("USAGE: sockconn <filename>"); exit(EXIT_FAILURE); } /* ソケット作成 */ if((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ exit(EXIT_FAILURE); } /* クライアント設定 */ memset(&cli, 0, sizeof(cli)); cli.sun_family = AF_UNIX; strncpy(cli.sun_path, argv[1], sizeof(cli.sun_path)); /* サーバへ接続 */ socklen = SUN_LEN(&cli); if(connect(sockfd, (struct sockaddr *)&cli, socklen)) { exit(EXIT_FAILURE); } printf("connected to socket %s\n", cli.sun_path); exit(EXIT_SUCCESS); } ●●●▲ クライアント側ここまで ▲●●● これから作成されたバイナリを同一フォルダに置いて、作成ユーザで、カレントディレクトリで実行しました。 以下が実行時の入出力です(カッコ内は実行順序)。 ■▼ サーバ側ここから ▼■ $ ./mksock jjj1…(1) $ socket available: jjj1, sockfd=3 $ sockResult = -1, sun_path=jjj1 $ mksock end ■▲ サーバ側ここから ▲■ ●▼ クライアント側ここから ▼● $ ./sockconn jjj1…(2) $ connected to socket jjj1 ●▲ クライアント側ここから ▲● 上記のように、サーバ側が accept 時に -1 を返却しています。 パーミッションについては以下になっています。 srwxr-xr-x 1 hoge hoge 0 2011-09-04 21:36 jjj1 -rwxr--r-- 1 hoge hoge 86870 2011-09-04 21:36 mksock -rwxr--r-- 1 hoge hoge 86775 2011-09-04 21:36 sockconn パーミッションを見る限り、ソケットファイルにはアクセスできているかと。 おそらく環境周りではないかと思いますが、考えつきません。 linux プログラミングに詳しいかた、よろしくお願いいたします。

  • Socket プログラミングについて

    先日の質問ではありがとうございました。 今回はソースコードについてですが もしよろしければアドバイスお願いします。 Socket 制御を行うアプリを作成しています。 ・クライアントアプリ ・サーバアプリ の2つから構成していまして同PC上で動作させます。 クライアントから localhost 経由でサーバアプリに接続。 サーバアプリは ServerSocket を生成して accept しています。 サーバアプリで accept により Socket を生成すると その Socket を Thread に引き渡して適宜処理を行います。 その後、 再び別クライアントからの接続を待つために サーバアプリで accept したいのですが そのまま accept を呼び出しても そこで待機せずに新しい Socket を生成しています。 別クライアントからの接続を待機するにはどうしたらいいのでしょうか? ご教授お願いします。

    • ベストアンサー
    • Java
  • Socket通信で、通信終了のイベントが発生しない

    クライアント(Windows)とサーバ(Unix)とSocket通信をするアプリを作っています。処理内容はクライアントのデータファイルをサーバに送信(アップデイト)し、サーバ側でデータを解析し、その結果を印刷するという手順です。 WinSockを使って、送信そのものはうまくいくのですが、サーバでデータを解析し結果を印刷するのに時間がかかり(10秒以上)、その間は送信終了のイベントが発生しません。これはサーバ側での処理を exec関数とwait関数で行っているので、正しい事態なのですが、データの送信が終わったら後はサーバ側で勝手にやって欲しいのです。サーバでの処理を system関数に置換えたり、バックグランド処理にしてもやはり処理が終わるまで送信終了のイベントが発生しません。何かいい方法をお教えください。

  • SocketのSend関数でのCLOSEの検知 [Linux]

    Linux環境でSocket(dm:PF_INET,type:SOCK_STREAM)を使用しての、 Client&ServerプログラムをCで作成しているのですが、 そこでのSend関数の使い方についてご助力ください。 Client&Serverプログラムは下記のような動きをします。 [Client] ServerへConnectした後、複数のDataを数秒間隔でServerへ 送信(send関数使用)します。受信(recvやread関数等)は、 一切行いません。 [Server] ClientからのConnectを受け付けた後、Clientから受信(recv関数 使用)したDataを標準出力へ表示する。送信(sendやwrite関数 等)は、一切行いません。 さて、ここでもしClientプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Server側のSocketが CLOSE_WAIT状態になった場合、Bufferに溜まっていたDataを すべて受けきった後、recv関数が0を返してくれるので 相手が終了したことがわかります。 ここからが質問のMainです。 では、もしServerプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Client側のSocketが CLOSE_WAIT状態になっても、CLOSE_WAIT直後のsend関数が なぜか正常に処理されてしまいます。無論このDataは、 Server側は受け取りません。この次のsend関数実行時に EPIPEが返ってくるので、ここでようやくSocketが切断された ことが判ります。 これを何とかCLOSE_WAIT状態になった直後から、send関数で 切断を検知できるようにできないでしょうか。 よろしくお願いします。 以上

  • Javaの断続的なSocket通信について

    Java標準のSocketクラスで通信プログラムを作ろうと思うのですが、インターネットで散見できるサンプルはだいたい単一のデータを送ってそのままプログラムを終わらせてしまうため、繰り返しデータを送る場合のプログラミングの方法がいまいちわかりません。 同一の接続先に断続的にデータを送信する場合は、新しいデータごとにSocketクラスを作り直さないといけないのでしょうか。それとも既存のSocketクラスのメソッドを使ってループ内で送信の待機をさせるのでしょうか。

  • ソケット通信(telnet)を行いたい

    現在、クライアントプログラムをアプレットで作ってます。 サーバ側はsocketで通信できる状態で、telnetで会話できます。 そこで質問なのですが、クライアント側でのsocket通信時の手順がわかりません。。 ソケットの入門書でわかったのはここまでです。 Socket s = new Socket("10.255.50.14", 23); でソケットを作るところはわかるのですが、そこからの手順がわかりません。。 ここから、connectとか使うのでしょうが、、 どなたかご存知の方がいらっしゃいましたらお教え願いたいと思います。

    • ベストアンサー
    • Java
  • Socket通信プログラム

    VisualC++6.0(SDK)を用いてSocket通信(UDP)プログラムを 作成(チャットやメッセンジャーのようなもの)しています。 送信用と受信用 1つのプログラムにて、送受信両方の機能を兼ね備えたものを作成しようと思っています。 で、送信側から送ったデータを受信側で処理(文字列の追加など)をして 受信側から送信側に送り戻したいとおもいます。 送信ボタンにより送信します。受信したデータはエディットボックスに表示します。 が、受信したデータを送り返すとしているために、 いつまでも、受信->送信->受信・・・・を繰り返してしまいます。 これを、正しく動作するようにするには、どのようにしたら良いのでしょうか? ご存知の方宜しくお願い致します。 足りないものがあったら、補足させていただきます。

  • Socket + XML

    ・クライアントはサーバへXML形式のクエリを送信し、 ・サーバからXML形式のデータを受け取る という単純なプログラムを実装しています。 しかしサーバ側の、InputStreamを引数とするXMLパースメソッドでwaitしてしまって困っています。 かといって、クライアント側のOutputStreamを閉じると、クライアントのソケット自体も閉じてしまいます。 なるべく一度のコネクションで送受信を終了させたいのですが、よい方法はないでしょうか? 一応、BufferedReaderを利用してXML文章を文字列に落としてから StringReaderをbuilder.parseの引数に与えることで解決出来てはいるのですがスマートではない気がしまして。 [Server側]  ServerSocket server_sock = new ServerSocket(12345);  Socket sock = server_sock.accept();  /* XMLパーサビルダ生成 */  DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();  DocumentBuilder builder = fact.newDocumentBuilder();  /* ドキュメント docIn の解析 */  Document docIn = builder.parse(sock.getInputStream());//ここから動かない(clientがoutputを終了するまで待っている?)  (略)  /* 結果ドキュメント docOut の構築*/  Document docOut = builder.newDocument();  (略)  /* docOut 送信 */  TransformerFactory tfactory = TransformerFactory.newInstance();  Transformer transformer = tfactory.newTransformer();  transformer.transform(new DOMSource(docOut), new StreamResult(sock.getOutputStream()));  sock.getInputStream().close();  sock.getOutputStream().close();  sock.close(); [Client側]  Socket sock = new Socket("localhost", 12345);  /* XMLパーサビルダ生成 */  DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();  DocumentBuilder builder = fact.newDocumentBuilder();  /* クエリドキュメント docOut の構築*/  Document docOut = builder.newDocument();  (略)  /* docOut 送信 */  TransformerFactory tfactory = TransformerFactory.newInstance();  Transformer transformer = tfactory.newTransformer();  transformer.transform(new DOMSource(docOut), new StreamResult(sock.getOutputStream()));  sock.getOutputStream().flush();  //sock.getOutputSream().close();//これにすると、socketが閉じてしまう  /* 結果ドキュメント docIn の解析 */  Document docIn = builder.parse(sock.getInputStream());//サーバから結果が送信されないので、クライアントはここで停止  (略)

    • ベストアンサー
    • Java
このQ&Aのポイント
  • Microsoft Surface GO3から出力ができない問題について相談します。印刷キューにデータは届くものの、プリンター側で印刷が中止され、出力されません。
  • お使いの環境はSurface GO3とWindows 11で、無線LAN経由で接続されています。
  • 関連するソフトやアプリは特にありません。電話回線の種類は不明です。
回答を見る

専門家に質問してみよう