前提・実現したいこと
>ここに質問の内容を詳しく書いてください。
「siv3d」を使ってゲームを作成しています。(v0.6.3)
https://zenn.dev/reputeless/books/siv3d-documentation
Visual Studio Community 2019 で編集しています。
多人数ボードゲームを作成するため、複数PCの通信機能を実装したいです。
サンプルにあった「1 対 1 の TCP 通信」を改造したのですが、うまくいきません。
発生している問題・エラーメッセージ
通信が繋がりません。
知識が足りないため、何が問題になり得るのかも想像すらついてません。基本設定を間違っているのかもしれません。
とりあえず、外部との通信でサンプルが動くようにしたいです。
問題点以外でも、基本的な注意事項など思いついたら教えていただけると助かります。
加えてこの問題以外に、時々以下のエラーが出て強制終了します。
dialog
1[std::runtime_error]close:ソケット以外のものに対して操作を実行しようとしました。:ソケット以外のものに対して操作を実行しようとしました。 2For more information, [Debug] -> [Windows] -> [Exception Settings] -> tick the C++ Exception checkbox under the [Break When Thrown] heading
該当のソースコード
チュートリアル 40 | TCP 通信
https://zenn.dev/reputeless/books/siv3d-documentation/viewer/tutorial-tcp
Siv3D_IPv4Address.ipp
https://github.com/Siv3D/OpenSiv3D/blob/main/Siv3D/include/Siv3D/detail/IPv4Address.ipp
cpp
1//サーバー側、サンプルそのまま 2# include <Siv3D.hpp> 3 4void Main() 5{ 6 // ポート番号 7 constexpr uint16 port = 50000; 8 bool connected = false; 9 10 TCPServer server; 11 server.startAccept(port); 12 13 Window::SetTitle(U"TCPServer: Waiting for connection..."); 14 15 Point clientPlayerPos{ 0, 0 }; 16 17 while (System::Update()) 18 { 19 const Point serverPlayerPos = Cursor::Pos(); 20 21 if (server.hasSession()) 22 { 23 if (not connected) // クライアントが接続 24 { 25 connected = true; 26 27 Window::SetTitle(U"TCPServer: Connection established!"); 28 } 29 30 // 送信 31 server.send(serverPlayerPos); 32 33 // 受信 34 while (server.read(clientPlayerPos)); 35 } 36 37 // クライアントが切断 38 if (connected && (not server.hasSession())) 39 { 40 // 切断 41 server.disconnect(); 42 43 connected = false; 44 45 Window::SetTitle(U"TCPServer: Waiting for connection..."); 46 47 // 新たな接続を受け付け開始 48 server.startAccept(port); 49 } 50 51 Circle{ serverPlayerPos, 30 }.draw(Palette::Skyblue); 52 53 Circle{ clientPlayerPos, 10 }.draw(Palette::Orange); 54 } 55}
cpp
1//クライアント側 2# include <Siv3D.hpp> 3# include <winsock.h> 4 5void Main() 6{ 7 // 接続先の IPv4 アドレス(今回は自身の PC なので Localhost) 8 IPv4Address ip = IPv4Address::Localhost(); 9 10 // ポート番号 11 constexpr uint16 port = 50000; 12 13 bool connected = false; 14 15 TCPClient client; 16 17 // 接続を試行 18 client.connect(ip, port); 19 20 Window::SetTitle(U"TCPClient: Waiting for connection..."); 21 22 //IP入力用テキストボックス 23 TextEditState te0; 24 TextEditState te1; 25 te1.text = U"Siv3D"; // デフォルトの文字列 26 TextEditState te2; 27 TextEditState te3; 28 29 30 Point serverPlayerPos{ 0, 0 }; 31 32 while (System::Update()) 33 { 34 const Point clientPlayerPos = Cursor::Pos(); 35 36 //IP入力用テキストボックス 37 SimpleGUI::TextBox(te0, Vec2{ 100, 140 }); 38 SimpleGUI::TextBox(te1, Vec2{ 100, 200 }); 39 SimpleGUI::TextBox(te2, Vec2{ 100, 260 }); 40 SimpleGUI::TextBox(te3, Vec2{ 100, 320 }); 41 42 if (SimpleGUI::Button(U"invite", Vec2{ 420, 200 })) 43 { 44 //ボタンが押された時、一旦通信切断 45 client.disconnect(); 46 47 connected = false; 48 49 Window::SetTitle(U"TCPClient: Waiting for connection..."); 50 51 //テキストボックスから文字列取得、数値型で仮保持。 52 //const String s = te1.text; 53 //std::string str = s.narrow(); 54 //ip = inet_addr(str.c_str()); 55 int32 num_a = ParseOr<int32>(te0.text, 10); 56 int32 num_b = ParseOr<int32>(te1.text, 10); 57 int32 num_c = ParseOr<int32>(te2.text, 10); 58 int32 num_d = ParseOr<int32>(te3.text, 10); 59 60 //IP変数に代入して、接続を再試行 61 ip = IPv4Address::IPv4Address(num_a, num_b, num_c, num_d); 62 // 接続を再試行 63 client.connect(ip, port); 64 } 65 66 if (SimpleGUI::Button(U"Clear", Vec2{ 420, 300 })) 67 { 68 client.disconnect(); 69 70 connected = false; 71 72 Window::SetTitle(U"TCPClient: Waiting for connection..."); 73 74 ip = IPv4Address::Localhost(); 75 // 接続を再試行 76 client.connect(ip, port); 77 } 78 79 if (client.isConnected()) 80 { 81 if (not connected) // 接続された 82 { 83 connected = true; 84 85 Window::SetTitle(U"TCPClient: Connection established!"); 86 } 87 88 // 送信 89 client.send(clientPlayerPos); 90 91 // 受信 92 while (client.read(serverPlayerPos)); 93 } 94 95 if (client.hasError()) // 切断/接続エラー 96 { 97 client.disconnect(); 98 99 connected = false; 100 101 Window::SetTitle(U"TCPClient: Waiting for connection..."); 102 103 // 接続を再試行 104 client.connect(ip, port); 105 } 106 107 Circle{ clientPlayerPos, 30 }.draw(Palette::Skyblue); 108 109 Circle{ serverPlayerPos, 30 }.draw(Palette::Orange); 110 } 111}
試したこと
>ここに問題に対して試したことを記載してください。
サンプルプログラムは同一pc上で通信する仕様で、想定通り動作しました。
次に改造したプログラムを同一pc上でテストしました。「IPv4Address::Localhost();の代入」「手動の"127.0.0.1"代入」「関係ないアドレスでのエラーチェック」いずれも想定通り動作しました。
その後上記のプログラムを2つのpcにて実行。
サーバー側のpcで「ipconfig」を実行し、イーサネットのIPv4アドレスを特定。
クライアント側で入力したところ、接続できず。
補足情報(FW/ツールのバージョンなど)
>ここにより詳細な情報を記載してください。
回答2件
あなたの回答
tips
プレビュー