質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google App Engine

Google App Engineは、Googleの管理するデータセンター上でウェブアプリケーションの開発が可能なクラウドコンピュータ技術です。Java、Python、Go用にSDKが用意されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Google Container Engine (GKE)

Google Container Engine (GKE) は、Dockerコンテナのオープンソース管理ソフトウェア、Kubernetesのクラスタを簡単にデプロイ可能にするサービスです。

Apache Maven

Apache Mavenは、ソフトウェアプロジェクトの管理ツールです。

Q&A

0回答

2192閲覧

Google Cloud PlatformでWebではないサービスを動かすには?

yuni

総合スコア15

Google App Engine

Google App Engineは、Googleの管理するデータセンター上でウェブアプリケーションの開発が可能なクラウドコンピュータ技術です。Java、Python、Go用にSDKが用意されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Google Container Engine (GKE)

Google Container Engine (GKE) は、Dockerコンテナのオープンソース管理ソフトウェア、Kubernetesのクラスタを簡単にデプロイ可能にするサービスです。

Apache Maven

Apache Mavenは、ソフトウェアプロジェクトの管理ツールです。

1グッド

1クリップ

投稿2016/04/21 10:09

Google Cloud PlatformでJavaのSTUNサーバーを動かしたいと考えております。
まず、GCPの公式チュートリアル通りにやってみました。これは成功しました。

今回の最終目標はGCP上でJavaのSTUNサーバーを動作させることなのですが、手始めにもっと単純なエコーサーバーを作ってテストしてみることにしました。
まずJavaでエコーサーバーを書きました。

Java

1package com.example.appengine.helloworld; 2 3import java.net.DatagramPacket; 4import java.net.DatagramSocket; 5import java.net.InetAddress; 6import java.nio.ByteBuffer; 7 8public class Main { 9 private static int port = 9696; 10 11 public static void main(String[] args) { 12 System.out.println("Server started."); 13 DatagramSocket socket; 14 try { 15 socket = new DatagramSocket(port); 16 }catch(Exception e) { 17 return; 18 } 19 20 while(true) { 21 try{ 22 byte buffer[] = new byte[1024]; 23 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 24 socket.receive(packet); 25 26 System.out.println("I received the data:"); 27 String str = new String(packet.getData()); 28 System.out.println(" " + str); 29 byte[] reply_data = packet.getData(); 30 DatagramPacket dp = new DatagramPacket(reply_data, reply_data.length, packet.getSocketAddress()); 31 socket.send(dp); 32 System.out.println("I did reply."); 33 } 34 catch(Exception e){ 35 e.printStackTrace(); 36 } 37 } 38 } 39 40} 41

次にC++でテキストを送信してから受信するプログラムを書きました。

C++

1#include <WinSock2.h> 2#pragma comment(lib, "ws2_32") 3#include <iostream> 4 5#pragma warning(disable:4996) 6 7static const int bufsize = 1024; 8 9int main() 10{ 11 WSADATA wsa; 12 WSAStartup(MAKEWORD(2, 2), &wsa); 13 14 SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 15 16 sockaddr_in sendaddr; 17 memset(&sendaddr, 0, sizeof(sendaddr)); 18 19 char data[bufsize] = ""; 20 21 sendaddr.sin_family = AF_INET; 22 23 while (true) 24 { 25 26 std::cout << "宛先のIPアドレスを入力してください(例 172.26.17.38)" << std::endl; 27 std::cin >> data; 28 sendaddr.sin_addr.s_addr = inet_addr(data); 29 30 std::cout << "宛先のポート番号を入力してください" << std::endl; 31 int port_num; 32 std::cin >> port_num; 33 sendaddr.sin_port = htons(port_num); 34 35 std::cout << "送信したいテキスト(~255文字)を入力すると送信されます" << std::endl; 36 std::cin >> data; 37 int send_res = sendto(sock, data, strlen(data) + 1, 0, (sockaddr *) &sendaddr, sizeof(sendaddr)); 38 if (send_res == -1) 39 { 40 std::cout << "failed to send" << std::endl; 41 } 42 else 43 { 44 std::cout << "送信しました。" << std::endl; 45 } 46 47 sockaddr_in cliant_addr; 48 int addr_len = sizeof(sockaddr_in); 49 50 int rec_size = recvfrom(sock, data, bufsize, 0, reinterpret_cast<sockaddr *>(&cliant_addr), &addr_len); 51 52 if (rec_size == -1) 53 { 54 std::cout << "failed to recvfrom" << std::endl; 55 int e = WSAGetLastError(); 56 std::cout << "error_code:" << e << std::endl; 57 return -1; 58 } 59 60 if (rec_size >= bufsize) 61 { 62 rec_size = bufsize; 63 } 64 data[rec_size-1] = '\0'; 65 66 std::cout << "received:" << data << std::endl; 67 } 68 69 closesocket(sock); 70 WSACleanup(); 71 72 return 0; 73} 74

念のためファイアウォールとアンチウィルスソフトを停止させた状態で127.0.0.1の9696ポートにデータを送信するテストをしてみると、先ほどのJavaプログラムが正常にエコーサーバーとしての仕事をこなしていることが確認できました。

これはEclipse上で動作させた場合の確認だったのですが、今度はチュートリアルに出てきたmvnコマンドを使って動作確認をしてみました。
まずjava-docs-samples/appengine/helloworldフォルダを複製してjava-docs-samples/appengine/echoフォルダに改名し、java-docs-samples/appengine/echo/src/main/java/com/example/appengine/helloworld/HelloServlet.javaの内容を先ほどのJavaプログラムで上書きしました。
そしてjava-docs-samples/appengine/echoディレクトリに移動して
mvn appengine:devserver
というコマンドを実行しました。
するとJavaプログラムが起動したのでもう一度同じように先ほどのC++プログラムを使ってデータを送ってみたのですがrecvfromが-1を返し、エラーコードはWSAECONNRESET (10054)でした。ということはsendto関数でデータグラムを送信したとき「ICMP ホストに到達不能」という状況になっているようです。残念ながらJavaプログラム側のログが表示されないので実際はどうなっているのか確認できませんが、Eclipseのときとは同じ動作をしてくれていないことは確かです。おそらくこれはWebサーバーを起動する専用のコマンドなのではないかと疑っていて、だから期待通りの動作をしてくれないのでしょう。そもそも、GCPでWebではないサービスを公開すること自体は可能なのでしょうか?

どうすればよいのでしょうか?
宜しくお願い致します。

ikuwow👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問