お疲れ様です。
現在、以下のプログラムにてUDP通信を行おうと考えています。
127.0.0.1及びの自身のLAN内では通信を行えたのですが、グローバルIP及びWANによる遠隔(近畿→関東)での通信に失敗してしまいます。
ポート開放はサーバー(受信側)のみ行う必要があるとのことでしたため、
support.eonet.jp/connect/net/multi_bbr/eo-rt100/quick/about_portmap.html
pc-karuma.net/windows-10-firewall-open-port/
umemasu2018.g1.xrea.com/
www.cman.jp/network/support/go_access.cgi
こちらに沿って
・プライベートIPを固定
・eo光の多機能ルーターよりポートマッピングを設定 (自IPアドレス、UDP、ポート番号9850-9851)
・ファイアウォールにてUDP、ポート番号9850-9851の開放
・上記でダメでしたため念のためUPnPCJで開放
を行いましたが接続できませんでした。
他にする必要のある作業はございますでしょうか…
又、以下のプログラムではおそらくクライアント側からの送信ができないかもと思っているのですが、ポート1つで送受信することはできるのでしょうか?
dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=past&no=2100
こちらに従ってMakeUDPSocket(-1)ぶぶんのポートを指定しましたがエラーとなりました。
#include <algorithm>
#include <string>
#include "DxLib.h"
//キー押し判定
class switchs {
public:
bool first{ false };//オンオフ判定
uint8_t second{ 0 };//プッシュ判定
public:
switchs(void) noexcept {
Init(false);
};
//使用前の用意
void Init(bool on) {
first = on;
second = 0;
}
//更新
void GetInput(bool key) {
second = std::clamp<uint8_t>(second + 1, 0, (key ? 2 : 0));
if (trigger()) {
first ^= 1;
}
}
//オンオフの取得
const bool on()const noexcept {
return first;
}
//押した瞬間
const bool trigger(void) const noexcept {
return second == 1;
}
//押している間
const bool press(void) noexcept {
return second != 0;
}
//離している間
const bool release(void) noexcept {
return second == 0;
}
};
switchs Ykey, Nkey;
switchs NumKey[10];
//
bool Mes_YN(const char* pMes,int *pSequence, int pSeqThis,bool* pAns) {
printfDx(pMes);
printfDx(" Y/N -> ");
if (*pSequence == pSeqThis) {
if (Ykey.trigger()) {
*pAns = true;
(*pSequence)++;
return true;
}
if (Nkey.trigger()) {
*pAns = false;
(*pSequence)++;
return true;
}
}
else if (*pSequence > pSeqThis) {
if (*pAns) {
printfDx("Y");
}
else {
printfDx("N");
}
}
printfDx("\n");
return false;
}
bool Mes_Num(const char* pMes, int *pSequence, int pSeqThis, int* pAns, int Min, int Max) {
printfDx(pMes);
if (*pSequence == pSeqThis) {
for (int i = 0; i < 10; i++) {
if (NumKey[i].trigger()) {
int num = (i + 1) % 10;
if (Min <= num && num <= Max) {
*pAns = (i + 1) % 10;
(*pSequence)++;
return true;
}
}
}
}
else if (*pSequence > pSeqThis) {
printfDx("%d", *pAns);
}
return false;
}
//
void Send(int pSeqThis, int UseNetUDPHandle, IPDATA& Ip, int SendPort, const char* Mes,int size) {
NetWorkSendUDP(UseNetUDPHandle, Ip, SendPort, Mes, size); // 文字列の送信
printfDx("%04d | ", pSeqThis);
printfDx("送信:[%d,%d,%d,%d][%d] Handle=[%d]\n", Ip.d1, Ip.d2, Ip.d3, Ip.d4, SendPort, UseNetUDPHandle);
}
char StrBuf_t[256]; // データバッファ
bool Recv(int* pSequence, int *pSeqThis, int UseNetUDPHandle,IPDATA* Ip, int* RecvPort) {
bool ans = false;
if (*pSequence == *pSeqThis) {
switch (CheckNetWorkRecvUDP(UseNetUDPHandle)) {
case TRUE:
NetWorkRecvUDP(UseNetUDPHandle, Ip, RecvPort, StrBuf_t, 256, FALSE); // 受信
ans = true;
printfDx("%04d | ", *pSeqThis);
printfDx("受信:[%d,%d,%d,%d][%d] Handle=[%d]\n", Ip->d1, Ip->d2, Ip->d3, Ip->d4, *RecvPort, UseNetUDPHandle);
printfDx(" | ");
printfDx("受信文言:[%s]\n", StrBuf_t);
break;
case FALSE:
//待ち
printfDx("%04d | ", *pSeqThis);
printfDx("受信待ち\n");
break;
default:
printfDx("%04d | ", *pSeqThis);
printfDx("エラー\n");
break;
}
}
return ans;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
SetMainWindowText(("SET_" + std::to_string(GetNowHiPerformanceCount())).c_str()); /*タイトル*/
SetGraphMode(640, 640, 16);
ChangeWindowMode(TRUE); /*窓表示*/
DxLib_Init();
SetAlwaysRunFlag(TRUE); /*background*/
SetLogFontSize(12);
int NetUDPHandle_Send = -1; // ネットワークハンドル
int NetUDPHandle_Recv = -1; // ネットワークハンドル
int Sequence = 0;
int SequenceSend = 0;
int SequenceRecv = 0;
int SendRecv = 0;
//
int UsePort = 9850;
bool Client = true;
int IP[12];
int PORT[5];
IPDATA SendIp; // 送信用IPアドレスデータ
IPDATA RecvIp; // 送信用IPアドレスデータ
int RecvPort = -1;
//
char StrBuf[256]; // データバッファ
unsigned long long Counter = 0;
while (ProcessMessage() == 0) {
//入力
Ykey.GetInput(CheckHitKey(KEY_INPUT_Y) != 0);
Nkey.GetInput(CheckHitKey(KEY_INPUT_N) != 0);
for (int i = 0; i < 10; i++) {
NumKey[i].GetInput(CheckHitKey(KEY_INPUT_1 + i) != 0);
}
//
SetDrawScreen(DX_SCREEN_BACK);
ClearDrawScreen();
{
clsDx();
bool OK = true;
printfDx("%04d | ", 0);
if (OK && Mes_YN("送信側か受信側か", &Sequence, 0, &Client)) { OK = false; }
if (Sequence > 0) {
if (Sequence == 1) {
SetMainWindowText(Client ? "送信者(クライアント)" : "受信者(サーバー)"); /*タイトル*/
Sequence++;
}
int SEL = 2;
//使用するポート選択
if (Sequence >= SEL) {
printfDx("%04d | ", SEL);
printfDx("ポート[");
int BUF = SEL;
for (int i = 0; i < 5; i++) {
if (OK && Mes_Num("", &Sequence, SEL, &PORT[SEL - BUF], 0, 9)) { OK = false; } SEL++;
}
printfDx("]\n");
if (Sequence == SEL) {
UsePort = (PORT[0] * 10000 + PORT[1] * 1000 + PORT[2] * 100 + PORT[3] * 10 + PORT[4]);
}
}
if (Sequence >= SEL) {
if (Client) {
//サーバーのIP入力
if (Sequence >= SEL) {
printfDx("%04d | ", SEL);
printfDx("IPアドレス[");
int BUF = SEL;
for (int i = 0; i < 4; i++) {
if (OK && Mes_Num((i == 0) ? "" : ".", &Sequence, SEL, &IP[SEL - BUF], 0, 2)) { OK = false; } SEL++;
if (OK && Mes_Num("", &Sequence, SEL, &IP[SEL - BUF], 0,
((!(IP[SEL - 2 - 1] == 2)) ? 9 : 5)
)) {
OK = false;
} SEL++;
if (OK && Mes_Num("", &Sequence, SEL, &IP[SEL - BUF], 0,
((!((IP[SEL - BUF - 2] == 2) && (IP[SEL - BUF - 1] == 5))) ? 9 : 5)
)) {
OK = false;
} SEL++;
}
printfDx("]\n");
if (Sequence == SEL) {
SendIp.d1 = (unsigned char)(IP[0] * 100 + IP[1] * 10 + IP[2]);
SendIp.d2 = (unsigned char)(IP[3] * 100 + IP[4] * 10 + IP[5]);
SendIp.d3 = (unsigned char)(IP[6] * 100 + IP[7] * 10 + IP[8]);
SendIp.d4 = (unsigned char)(IP[8] * 100 + IP[10] * 10 + IP[11]);
}
}
//入力シーケンスを過ぎたら
if (Sequence >= SEL) {
// 送信用ソケットを作って初送信
if (NetUDPHandle_Send == -1) {
NetUDPHandle_Send = MakeUDPSocket(-1);
if (NetUDPHandle_Send != -1) {
Send(SEL, NetUDPHandle_Send, SendIp, UsePort, "通信リクエスト", 15); SEL += 1;//通信開始(分けなくてもよさそう)
}
}
//受信
if (NetUDPHandle_Send != -1) {
//クライアントからのデータを受信
if (NetUDPHandle_Recv == -1) {
NetUDPHandle_Recv = MakeUDPSocket(UsePort + 1);
}
if (Recv(&SequenceRecv, &SendRecv, NetUDPHandle_Recv, &RecvIp, &RecvPort)) {
SequenceRecv++;
SendRecv++;
}
//自身のデータを送信
Send(Counter, NetUDPHandle_Send, RecvIp, UsePort, (std::string("クライアント->") + std::to_string(Counter%10)).c_str(), 15);
Counter++;
}
}
}
else {
//サーバー
// UDP通信用のソケットハンドルを作成
if (NetUDPHandle_Recv == -1) {
NetUDPHandle_Recv = MakeUDPSocket(UsePort);
}
//該当ソケットにクライアントから受信
if (Recv(&SequenceRecv, &SendRecv, NetUDPHandle_Recv, &RecvIp, &RecvPort)) {
SequenceRecv++;
SendRecv++;
//サーバーからクライアントに返信
{
if (NetUDPHandle_Send == -1) {
NetUDPHandle_Send = MakeUDPSocket(-1);
}
if (NetUDPHandle_Send != -1) {
Send(Counter, NetUDPHandle_Send, RecvIp, UsePort + 1, (std::string("サーバー->") + std::to_string(Counter % 10)).c_str(), 15);
Counter++;
}
}
}
}
}
}
}
ScreenFlip();
}
if (NetUDPHandle_Send != -1) {
DeleteUDPSocket(NetUDPHandle_Send); // UDPソケットハンドルの削除
}
if (NetUDPHandle_Recv != -1) {
DeleteUDPSocket(NetUDPHandle_Recv); // UDPソケットハンドルの削除
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}