Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.175] |
|
Сообщ.
#1
,
|
|
|
Windows, WinSock.
Создается сокет, привязывается к локальному ip-адресу (127.0.0.1, порт 8000), вызывается listen, а потом accept, получаем клиентское соединение, получаем данные, которые прислал клиент. Набрав в адресной строке браузера 127.0.0.1:8000, или [ip-адрес в локальной сети]:8000, серверу будет послан запрос от веб-браузера, который отобразится в консольном окне приложения, код которого представлен ниже. Как сделать так, чтобы я мог обращаться к этому серверному приложению из браузера по внешнему ip-адресу и порту, чтобы точно также браузер посылал свой запрос этому серверному приложению? Я так понял bind привязывает сокет только к адресу в локальной сети. Как же быть? Свой текущий ip-адрес я могу посмотреть, например здесь https://2ip.ru/. Как по нему обратится к моему серверу (код ниже)? #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib, "Ws2_32.lib") #include <iostream> using namespace std; in_addr getMyIP(){ char buffer[100]; ::gethostname(buffer,100); hostent* ipAddr = ::gethostbyname(buffer); in_addr addr; memcpy(&addr,ipAddr->h_addr_list[0], sizeof(unsigned long)); return addr; } char data[300] = {0}; int main(){ int error; setlocale(LC_ALL,"Russian_Russia.1251"); WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); struct addrinfo* addr = NULL; struct addrinfo hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; getaddrinfo("127.0.0.1", "8000", &hints, &addr); //getaddrinfo(inet_ntoa(::getMyIP()), "8000", &hints, &addr);//getMyIP() возвращает мой ip в локальной сети //getaddrinfo("###.###.###.###", "8000", &hints, &addr);//вместо "###.###.###.###" - мой текущий внешний ip, отображаемый например здесь https://2ip.ru/ int serverSocket = socket(addr->ai_family, addr->ai_socktype,addr->ai_protocol); int r = bind(serverSocket, addr->ai_addr, (int)addr->ai_addrlen); if(r==SOCKET_ERROR){ error = WSAGetLastError(); printf("Не удалось привязать адрес к сокету.\nКод ошибки -- %i\n",error); } listen(serverSocket, 1); printf("Ожидание присоединения клиента...\n"); int clientSocket = accept(serverSocket, NULL, NULL); if(clientSocket==INVALID_SOCKET){ error = WSAGetLastError(); printf("Не удалось получить клиентское соединение.\nКод ошибки -- %i\n",error); }else{ printf("Клиентское соединение получено.\n"); } int rin = ::recv(clientSocket,data,300,0); if(rin>0){//данные сервера приняты cout<<"запрос клиента:\n"; cout<<data; } system("pause"); } |
Сообщ.
#2
,
|
|
|
Надо bind делать на адрес 0.0.0.0:8000, тогда сервер будет слушать на всех интерфейсах.
|
Сообщ.
#3
,
|
|
|
Цитата Pacific @ Надо bind делать на адрес 0.0.0.0:8000, тогда сервер будет слушать на всех интерфейсах. Если сделать так, то теперь я могу одновременно обращаться к серверу так 192.168.100.37:8000 (мой адрес в локальной сети) или так 127.0.0.1:8000. Но мне нужно обращаться к моему серверному приложению по внешнему IP и порту, то есть по ip который отображается например здесь https://2ip.ru/. |
Сообщ.
#4
,
|
|
|
Цитата riden @ Если внешний IP не привязан ни к одному интерфейсу, то повесить приложение на него не удастся.Но мне нужно обращаться к моему серверному приложению по внешнему IP и порту, то есть по ip который отображается например здесь https://2ip.ru/. В таком случае приложение вешается на IP интерфейса, через который компьютер выход в Интернет. Если компьютер подключен через роутер, то нужно на нем пробросить 8000 порт на IP интерфейса компьютера (на 192.168.100.37). |
Сообщ.
#5
,
|
|
|
Цитата simsergey @ ... через роутер, то нужно на нем пробросить 8000 порт на IP интерфейса компьютера (на 192.168.100.37). Скажите пожалуйста как это сделать. |
Сообщ.
#6
,
|
|
|
Ды обычно очень просто.
Эта тема заезженная. Вот например тут инструкции. Другое дело, если бы это делать самой программой, так было бы интереснее. Но мне не приходилось. Можно самой программой по технологии UPnP делать проброс порта на роутере. |
Сообщ.
#7
,
|
|
|
Цитата simsergey @ Ды обычно очень просто. Эта тема заезженная. Вот например тут инструкции. Другое дело, если бы это делать самой программой, так было бы интереснее. Но мне не приходилось. Можно самой программой по технологии UPnP делать проброс порта на роутере. Открыл порт в настройках роутера. http://2ip.ru показывает, что порт 8000 открыт. При проверке порта, на этом сайте, серверное приложение (код ниже) пишет "Клиентское соединение установлено". Но, если в адресной строке браузера набрать мой внешний ип и порт (###.###.###.###:8000), то по-прежнему ничего не происходит. При этом если набрать 192.168.100.37:8000 то все будет работать как и ожидается: в окне серверного приложения отобразится запрос веб-браузера. Что не так? #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib, "Ws2_32.lib") #include <iostream> using namespace std; char data[300] = {0}; int main(){ int error; setlocale(LC_ALL,"Russian_Russia.1251"); WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); struct addrinfo* addr = NULL; struct addrinfo hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; getaddrinfo("192.168.100.37", "8000", &hints, &addr); int serverSocket = socket(addr->ai_family, addr->ai_socktype,addr->ai_protocol); int r = bind(serverSocket, addr->ai_addr, (int)addr->ai_addrlen); if(r==SOCKET_ERROR){ error = WSAGetLastError(); printf("Не удалось привязать адрес к сокету.\nКод ошибки -- %i\n",error); } listen(serverSocket, 1); printf("Ожидание присоединения клиента...\n"); int clientSocket = accept(serverSocket, NULL, NULL); if(clientSocket==INVALID_SOCKET){ error = WSAGetLastError(); printf("Не удалось получить клиентское соединение.\nКод ошибки -- %i\n",error); }else{ printf("Клиентское соединение получено.\n"); } int rin = ::recv(clientSocket,data,300,0); if(rin>0){//данные сервера приняты cout<<"запрос клиента:\n"; cout<<data<<"\n"; } system("pause"); } |
Сообщ.
#8
,
|
|
|
Цитата riden @ А это уже или баг винды или роутера. Я с таким раньше сталкивался, когда не получается зайти на свой внешний IP.Но, если в адресной строке браузера набрать мой внешний ип и порт (###.###.###.###:8000), то по-прежнему ничего не происходит. Если Вы порт пробросили правильно, то остальные должны его видеть, ну а Вам остается коннектится на локальный. Добавлено Кстати, появление такого можно дополнительно проверить, повесив, скажем, http или ftp сервер, пробросив порт и на него. |