
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.173] |
![]() |
|
![]() |
|
|
Здравствуйте уважаемые форумчане. Сразу прошу прощения за возможно столь глупый вопрос но я учусь и стараюсь продвигаться вперед.
С++ начал изучать недавно,после 4х лет программирования на Delphi,но суть одна,потому здесь проблем,думаю,не будет. К сожалению после длительных поисков в "гугле" так и не нашел ответа на свой вопрос. Моя проблема заключается в создании банального клиент-серверного приложения. ___ Само приложение довольно легко написать (в интернете полно исходников и книг посвященных этой теме),но вопрос состоит в том что при написании сервера он висит на 127.0.0.1 адресе (то-есть локальном) и при коннекте с локального компьютера (с клиента) все прекрасно работает,но я никак не могу понять как заставить работать программу через Интернет,то-есть коннектится не через локальный адрес,а через внешний (в моем случае он 194.44.125.193) ___ IP и динамический,но насколько я понимаю пока я не перезагрузил модем он остается прежним,то-есть если я запускаю сервер у себя на компьютере,а на клиенте подключаюсь уже к внешнему IP программа должна работать,но этого не происходит ?? ___ Что я делаю не так и что нужно сделать для того что б я мог просто соединить 2 программы (клиент - сервер) зная внешний IP адрес сервера ? Я понимаю что желательно иметь статический IP для такой цели .. но как быть в моем случае .. * * * * * * Суть вопроса такова: нужно организовать передачу строки (эхо-сервер) между клиентом и сервером,но размещенных на разных компьютерах в просторах Интернета,зная внешние IP адреса каждого из них без использования посреднических серверов. Просто связь ip2ip Вод так .. извините за возможные косяки,просто объясните пожалуйста на пальцах что мне для этого надо,в какую сторону рыть ? ![]() |
Сообщ.
#2
,
|
|
|
Покажи код инициализации сервера на прослушку порта.
|
Сообщ.
#3
,
|
|
|
IP компа локальный или реальный?
![]() ![]() ipconfig /all Модем это роутер или? |
Сообщ.
#4
,
|
|
|
Цитата justscript @ Просто связь ip2ip Если быть точным, это называется P2P (peer-to-peer) ![]() Погугли по следующим словам, чтобы понять точнее, чего хочешь: DynDNS NAT, NAT traversal, STUN Если вкратце, то путь твой вовсе не будет устлан благоухающими розами. В ряде случаев без внешнего третьестороннего сервиса - никак. |
Сообщ.
#5
,
|
|
|
использую дома D-Link DSL-2640U
____ ipconfig /all: ![]() ![]() Microsoft Windows [Version 6.1.7601] (c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены. C:\Users\JustScript>ipconfig /all Настройка протокола IP для Windows Имя компьютера . . . . . . . . . : JustScript-ПК Основной DNS-суффикс . . . . . . : Тип узла. . . . . . . . . . . . . : Гибридный IP-маршрутизация включена . . . . : Нет WINS-прокси включен . . . . . . . : Нет Ethernet adapter Сетевое подключение Bluetooth: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Устройства Bluetooth (личной сети) Физический адрес. . . . . . . . . : 70-F3-95-7B-C1-FD DHCP включен. . . . . . . . . . . : Да Автонастройка включена. . . . . . : Да Адаптер беспроводной локальной сети Беспроводное сетевое соединение: DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : [CommView] Atheros AR9285 802.11b/g/n WiF i Adapter Физический адрес. . . . . . . . . : C4-46-19-36-F9-03 DHCP включен. . . . . . . . . . . : Да Автонастройка включена. . . . . . : Да Локальный IPv6-адрес канала . . . : fe80::182d:248c:1105:f437%11(Основной) IPv4-адрес. . . . . . . . . . . . : 192.168.1.5(Основной) Маска подсети . . . . . . . . . . : 255.255.255.0 Аренда получена. . . . . . . . . . : 29 августа 2011 г. 13:08:10 Срок аренды истекает. . . . . . . . . . : 30 августа 2011 г. 13:08:10 Основной шлюз. . . . . . . . . : 192.168.1.1 DHCP-сервер. . . . . . . . . . . : 192.168.1.1 IAID DHCPv6 . . . . . . . . . . . : 230966809 DUID клиента DHCPv6 . . . . . . . : 00-01-00-01-15-64-4A-F6-60-EB-69-07-2A-1F DNS-серверы. . . . . . . . . . . : 192.168.1.1 NetBios через TCP/IP. . . . . . . . : Включен Ethernet adapter Подключение по локальной сети: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Сетевая карта Realtek RTL8168D/8111D Fami ly PCI-E Gigabit Ethernet NIC (NDIS 6.20) Физический адрес. . . . . . . . . : 60-EB-69-07-2A-1F DHCP включен. . . . . . . . . . . : Да Автонастройка включена. . . . . . : Да Туннельный адаптер Reusable ISATAP Interface {96F5D2E7-6CFA-42CA-9E31-D03A46D689 95}: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Адаптер Microsoft ISATAP Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да Туннельный адаптер isatap.{9DB3E848-34CE-4E98-87A7-AB4DED7BBE4B}: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Адаптер Microsoft ISATAP #3 Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да Туннельный адаптер Reusable ISATAP Interface {015AC1A5-F812-450C-B831-1EB249728A 3C}: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Адаптер Microsoft ISATAP #4 Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да Туннельный адаптер Reusable ISATAP Interface {9930F15D-9087-4CFA-AC71-3DBFF7225A 95}: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Адаптер Microsoft ISATAP #5 Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да Туннельный адаптер Teredo Tunneling Pseudo-Interface: DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да IPv6-адрес. . . . . . . . . . . . : 2001:0:5ef5:79fd:2c9b:3a27:3dd3:4ad(Основ ной) Локальный IPv6-адрес канала . . . : fe80::2c9b:3a27:3dd3:4ad%22(Основной) Основной шлюз. . . . . . . . . : :: NetBios через TCP/IP. . . . . . . . : Отключен Туннельный адаптер Reusable ISATAP Interface {D25AE2E2-C991-41D3-A0B9-6BFA2DD37D 9C}: Состояние среды. . . . . . . . : Среда передачи недоступна. DNS-суффикс подключения . . . . . : Описание. . . . . . . . . . . . . : Адаптер Microsoft ISATAP #8 Физический адрес. . . . . . . . . : 00-00-00-00-00-00-00-E0 DHCP включен. . . . . . . . . . . : Нет Автонастройка включена. . . . . . : Да C:\Users\JustScript> ____ Пробую на примере приложений с MSDN Сервер: ![]() ![]() #undef UNICODE #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> // Need to link with Ws2_32.lib #pragma comment (lib, "Ws2_32.lib") // #pragma comment (lib, "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int __cdecl main(void) { WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; struct addrinfo *result = NULL; struct addrinfo hints; int iSendResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } // No longer need server socket closesocket(ListenSocket); // Receive until the peer shuts down the connection do { iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { printf("Bytes received: %d\n", iResult); // Echo the buffer back to the sender iSendResult = send( ClientSocket, recvbuf, iResult, 0 ); if (iSendResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } printf("Bytes sent: %d\n", iSendResult); } else if (iResult == 0) printf("Connection closing...\n"); else { printf("recv failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } } while (iResult > 0); // shutdown the connection since we're done iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } // cleanup closesocket(ClientSocket); WSACleanup(); return 0; } Клиент: ![]() ![]() #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> // Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int __cdecl main(int argc, char **argv) { WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints; char *sendbuf = "this is a test"; char recvbuf[DEFAULT_BUFLEN]; int iResult; int recvbuflen = DEFAULT_BUFLEN; // Validate the parameters if (argc != 2) { printf("usage: %s server-name\n", argv[0]); return 1; } // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // Resolve the server address and port iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Attempt to connect to an address until one succeeds for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (ConnectSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } // Connect to server. iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"); WSACleanup(); return 1; } // Send an initial buffer iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 ); if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } printf("Bytes Sent: %ld\n", iResult); // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } // Receive until the peer closes the connection do { iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); if ( iResult > 0 ) printf("Bytes received: %d\n", iResult); else if ( iResult == 0 ) printf("Connection closed\n"); else printf("recv failed with error: %d\n", WSAGetLastError()); } while( iResult > 0 ); // cleanup closesocket(ConnectSocket); WSACleanup(); return 0; } или даже приложение написаное мной по урокам Delphi Сервер: ![]() ![]() program server; {$APPTYPE CONSOLE} uses Windows, SysUtils, ScktComp; type ServSock = class(Tobject) ServerSocket:TServerSocket; procedure xAccept(Sender: TObject; Socket: TCustomWinSocket); procedure xConnect(Sender:TObject; Socket:TCustomWinSocket); procedure xDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure xError (Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure xRead (Sender:TObject; Socket:TCustomWinSocket); // procedure xWrite (Sender: TObject; Socket: TCustomWinSocket); // procedure xGetSocket (Sender: TObject; Socket: Integer; // var ClientSocket: TServerClientWinSocket); // procedure xGetThread (Sender: TObject; ClientSocket: TServerClientWinSocket; // var SocketThread: TServerClientThread); procedure xListen (Sender: TObject; Socket: TCustomWinSocket); // procedure xThreadEnd (Sender: TObject; Thread: TServerClientThread); // procedure xThreadStart(Sender: TObject; Thread: TServerClientThread); public constructor Create; destructor Destroy; override; end; var Server1 : ServSock; {==============================================================================} Constructor ServSock.Create; Begin inherited Create; ServerSocket:=TServerSocket.Create(nil); ServerSocket.ServerType:=stNonBlocking; ServerSocket.OnAccept := xAccept; ServerSocket.OnClientConnect := xConnect; ServerSocket.OnClientDisconnect := xDisconnect; ServerSocket.OnClientError := xError; ServerSocket.OnClientRead := xRead; // incoming // ServerSocket.OnClientWrite := xWrite; // outgoing // ServerSocket.OnGetSocket := xGetSocket; // ServerSocket.OnGetThread := xGetThread; ServerSocket.OnListen := xListen; // ServerSocket.OnThreadEnd := xThreadEnd; // ServerSocket.OnThreadStart := xThreadStart; ServerSocket.Port:=8080; ServerSocket.Active:=true; End; {==============================================================================} Destructor ServSock.Destroy; Begin ServerSocket.Free; inherited Destroy; End; {==============================================================================} procedure ServSock.xError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin writeln('Error !!!'); end; {==============================================================================} procedure ServSock.xListen(Sender: TObject; Socket: TCustomWinSocket); begin writeln('Listening ..'); end; {==============================================================================} procedure ServSock.xRead(Sender:TObject; Socket:TCustomWinSocket); Begin Writeln(Socket.ReceiveText); End; {==============================================================================} procedure ServSock.xAccept(Sender: TObject; Socket: TCustomWinSocket); begin server1.ServerSocket.Socket.Connections[Server1.ServerSocket.Socket.ActiveConnections-1] .SendText('Accepted ..'); end; procedure ServSock.xConnect(Sender:TObject; Socket:TCustomWinSocket); Begin writeln('Client connected ['+IntToStr(Server1.ServerSocket.Socket.ActiveConnections)+']'); server1.ServerSocket.Socket.Connections[Server1.ServerSocket.Socket.ActiveConnections-1] .SendText('Connected ..'); End; {==============================================================================} procedure ServSock.xDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin writeln('Client disconected ..'); end; {==============================================================================} procedure _console; var text : string; i : integer; begin while true do begin readln(text); if text='q' then Server1.Destroy else begin for i:=0 to Server1.ServerSocket.Socket.ActiveConnections-1 do server1.ServerSocket.Socket.Connections[i].SendText('[SERVER]:'+Text); end; end; end; {==============================================================================} var msg : tmsg; var h : Cardinal; begin Server1 := ServSock.Create; h:=CreateThread(nil,0,@_console,nil,0,h); while GetMessage(MSG,0,0,0) do begin TranslateMessage(msg); DispatchMessage(msg); end; end. Клиент: ![]() ![]() program Client; {$APPTYPE CONSOLE} uses windows, sysutils, ScktComp; type ClientSock = class(Tobject) ClientSocket: TClientSocket; // procedure xConnect(Sender:TObject; Socket:TCustomWinSocket); // procedure xConnecting(Sender: TObject; Socket: TCustomWinSocket); // procedure xDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure xError (Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer); // procedure xLookup(Sender: TObject; Socket: TCustomWinSocket); procedure xRead (Sender: TObject; Socket: TCustomWinSocket); // procedure xWrite (Sender: TObject; Socket: TCustomWinSocket); public constructor Create; destructor Destroy; override; end; var Client1 : ClientSock; {==============================================================================} procedure ClientSock.xError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin writeln('Error !!!'); end; {==============================================================================} procedure ClientSock.xRead(Sender: TObject; Socket: TCustomWinSocket); begin writeln(Socket.ReceiveText); end; {==============================================================================} constructor ClientSock.Create; begin inherited Create; ClientSocket:=TClientSocket.Create(nil); ClientSocket.ClientType:=ctNonBlocking; // ClientSocket.OnConnect := xConnect; // ClientSocket.OnConnecting := xConnecting; // ClientSocket.OnDisconnect := xDisconnect; ClientSocket.OnError := xError; // ClientSocket.OnLookup := xLookup; ClientSocket.OnRead := xRead; // incoming // ClientSocket.OnWrite := xWrite; // outgoing ClientSocket.Address:='127.0.0.1'; ClientSocket.Port:=8080; ClientSocket.Active:=True; end; {==============================================================================} destructor ClientSock.Destroy; begin ClientSocket.Free; inherited; end; {==============================================================================} procedure _console; var text : string; begin while true do begin readln(text); if text='q' then Client1.Destroy else Client1.ClientSocket.Socket.SendText('[CLIENT]:'+Text) end; end; {==============================================================================} var msg : tmsg; var h : Cardinal; begin Client1 := ClientSock.Create; h:=CreateThread(nil,0,@_console,nil,0,h); while GetMessage(MSG,0,0,0) do begin TranslateMessage(msg); DispatchMessage(msg); end; end. _____ Ну я так понял что даже если мне и удастся наладить связь,то не на всех компьютерах приложения будут работать корректно,потому лучшим вариантом будет использовать сторонний сервер для организации связи .. Если я правильно Вас понимаю - то нужно написать PHP код для сервера и взаимодействовать через него ? Или есть более изящные решения ? Спасибо наперед ..) Добавлено Цитата Uncle_Bob @ IP компа локальный или реальный? На сколько я понимаю реальный,просто зашел на сайт http://2ip.ru/ и увидел свой IP ![]() или я не прав ? ![]() |
Сообщ.
#6
,
|
|
|
Цитата justscript @ На сколько я понимаю реальный,просто зашел на сайт http://2ip.ru/ и увидел свой IP или я не прав ? Ну, я сейчас тоже зашёл туда. Вижу какой-то IP из динамического пула своего провайдера. Только откуда ж этот сайт узнает, что я сидю за маршрутизатором, в который приходит провайдровский интернет, и реальный IP у меня совсем иной, и девайсов тоже за маршрутизатором несколько (и всякие мобилки через WiFi) ![]() |
Сообщ.
#7
,
|
|
|
Цитата Mr.Delphist @ Ну, я сейчас тоже зашёл туда. Вижу какой-то IP из динамического пула своего провайдера. Только откуда ж этот сайт узнает, что я сидю за маршрутизатором, в который приходит провайдровский интернет, и реальный IP у меня совсем иной, и девайсов тоже за маршрутизатором несколько (и всякие мобилки через WiFi) ![]() Уммс кажется я понял .. реальный - это НЕ внешний .. понятно .. спасибо большее .. буду еще учится .. на свой вопрос ответ получил - нужно просто понять всю иерархию сети. Буду читать ![]() ![]() |