Как-то в ксакепе наткнулся на статью "управление компьютером через телефон". На компе запускается простенькая серверная часть, которая при доступе к компьютеру выдает html-страницу, через которую можно выполнять некоторые действия(открыть\закрыть cd-rom и т д). Если комп не подключен к интернету - все нормально: набиваю в браузере http://127.0.0.1 - и страница появляется. При подключении к интернету возникают проблемы.... Я использую билайновский юсб-модем и выход в интернет не прямой. Т е я вхожу в какую-то билайновскую сеть компьютеров, которая выходит в интернет через один компьютер-шлюз. Таким образом у меня есть 2 ip-адреса: адрес моего компьютера в локальной сети билайна и адрес этого компьютера-шлюза, через который вся сеть юзает интернет. Как же быть? Могу ли я как-то прорваться через эти иерархические сетевые дебри? Вот код серверной части(клиентская часть - любой браузер) Код (Text): /* *If you'll find any errors, please contact me (mailto:dinamius@mail.ru) *Copyright (C) 2000-2002 Steve Kandrushin */ #include <windows.h> #include <winsock.h> #include <mmsystem.h> //To make program more small #pragma comment(linker,"/MERGE:.rdata=.text") //Соединяем сегменты данных и кода #pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078") #pragma comment(linker,"/ENTRY:MyWinMain") #pragma comment(linker,"/NODEFAULTLIB") //WML char s[20][62]= { "HTTP/1.1 200 OK\r\nContent-Type: text/vnd.wap.wml\r\n\r\n", "<?xml version = \"1.0\"?>\r\n<!DOCTYPE wml PUBLIC \"-//WAPFORUM", "//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">", "\r\n<wml>\r\n<card id=\"Card1\" title=\"My Computer\">\r\n<p>", "<a href=\"opencd\">OpenCD</a><br/>\r\n", "<a href=\"closecd\">CloseCD</a><br/>\r\n", // "<a href=\"swapms\">SwapMS</a><br/>\r\n", "<a href=\"shut\">Shut Down</a><br/>\r\n", "<a href=\"reset\">Reset</a><br/>\r\n", "<a href=\"logoff\">LogOFF</a><br/>\r\n", "</p>\r\n</card>\r\n</wml>\r\n" }; /*//HTML char s[8][50]= { "HTTP/1.1 200 OK\r\nContent-Type: text/html;", "charset=windows-1251\r\n\r\n", "<html><title><<<FULL CONTROL>>></title><body>", "<a href=\"opencd\">OpenCD</a><br>", "<a href=\"closecd\">CloseCD</a><br>", "<a href=\"reset\">Reset</a><br>", "<a href=\"off\">OFF</a><br>", "</body></html>" }; */ u_long crc32_table[256]; //Standart polynomial #define CRC32_POLY 0xEDB88320; //Initializating crc32 table void init_crc32() { int i, j; u_long c; for (i = 0; i < 256; ++i) { for (c = i << 24, j = 8; j > 0; --j) //c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : c << 1; if(c & 0x80000000){c=(c << 1) ^ CRC32_POLY;} else {c=(c << 1);}; crc32_table[i] = c; } } //Count crc32 u_long crc32(u_char *buf) { u_char *p= buf; u_long crc; crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ while(*p!=0) { crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *(p++)]; if(*p==32) break; }; return ~crc; /* transmit complement, per CRC-32 spec */ } //Return position of n space int space(char * word, int n) { if(n==0) return -1; int nbsp=0; for(int i=0; i<strlen((char *)word); i++) if(word[i]==32) if(++nbsp==n) return i; return -666;//No such space } //Return n word word[0], word[1],... char temp[1000]; char * get(char * word, int n) { int j=0; if(space(word, n)!=-666) for(int i=space(word, n)+1; i<strlen(word); i++) { if(word[i]==32) break; else temp[j++]=word[i]; } temp[j]=0; return temp; }; //Convert all english symbols to hi register u_char * UpString(u_char * str) { int i=-1; while(str[++i]!=0) if((str[i]>96)&&(str[i]<123)) str[i]=str[i]&0xDF; return str; }; void MyWinMain(void) { DWORD size, nr; boolean ButSwap=false; //For mouse buttons swap char Buff[1000]; init_crc32(); HANDLE out = CreateFile("C:\\dataxxx.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); WSADATA WSAData; WSAStartup(MAKEWORD(1,1), &WSAData); SOCKET Sock0 = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in name; name.sin_family = AF_INET; name.sin_port = htons(80); name.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(Sock0, (struct sockaddr FAR *) &name, sizeof(name))==SOCKET_ERROR)ExitProcess(0); listen(Sock0, 5); again: SOCKET Sock1=accept(Sock0, NULL, NULL); while(true) { ioctlsocket(Sock1, FIONREAD, &size); if(size>0) { recv(Sock1,(char *)Buff,1000,0); //receive text WriteFile(out, &Buff, size, &nr, NULL); // Write2File // Send data to cellphone for(int i=0; i<12; i++) { send(Sock1, s[i], strlen(s[i]), 0); WriteFile(out, &s[i], strlen(s[i]), &nr, NULL); } closesocket(Sock1); if( crc32(UpString( (u_char *)get(Buff, 0)))==0xA10411F ) //If == GET switch( crc32(UpString( (u_char *)get(Buff, 1))) ) { //OPENCD case 0x52AD375F: mciSendString("SET CDAUDIO DOOR OPEN WAIT",0,0, 0); break; //CLOSECD case 0x3918CCDF: mciSendString("SET CDAUDIO DOOR CLOSED WAIT",0,0, 0); break; //SWAPMS case 0x334993FF: ButSwap=!ButSwap;SwapMouseButton(ButSwap); break; //SHUT case 0xE4F1DC3F: ExitWindowsEx(EWX_POWEROFF, 0); break; //RESET case 0x54DF1B7F: ExitWindowsEx(EWX_REBOOT, 0); break; //LOGOFF case 0x838B5D5F: ExitWindowsEx(EWX_LOGOFF, 0); break; } goto again; } }; CloseHandle(out); }
Это понятно. Вопрос в другом: как подключиться к компьютеру, у которого нет прямого выхода в интернет? Например, мне известно, что некоторые онлайн-игры маил.ру и контакта(шахматы) используют прямое соединение между двумя компьютерами. А значит, один из компьютеров является сервером, а другой - клиентом. И никакие наты не мешают...
А как же тогда у меня скайп нормально работает? Хотя мой компьютер за натом. У моего друга тоже usb-мопед, и мы оба можем общаться по скайпу, хотя оба за натом... А скайп, насколько мне известно, использует p2p соединение
ну дык используется сервер посредник в таком случае, у которого ip выделенный , и организовуй общение через него или доплати и воспользуйся услугой у прова статического ip
BadGuy777 совершенно не обязательно. вполне может использоваться одноуровневые подключения. чтоб получить ип используются фиксированные посредники.
А проще всего, наверное, воспользоваться существующими серверами ICQ или IRC. И управлять удаленным компьютером через сообщения в чате
Наоборот. Чаще всего элементарно. Для этого надо просто сделать пробить NAT. У нас 2 протокола udp и tcp. Которые функционируют по разному. Так вот чтобы UDP функционировал. Нужна обратная связь, не обязательно но желательно. Поэтому NAT сервер в обязательном порядке запоминает адрес и порт отправителя и назначения. И помнит в течение определенного времени. Чтобы связь начала работать. Оба клиента должны отправить пакеты друг дружке. Тогда NAT зарегистрирует у себя порты и они смогут работать. Для удобства пользования применяют внешний сервер. Так как порты меняются, должны меняться. То каждый раз надо как-кто узнавать порт и IP. Вот клиенты конктятся на известный сервер с известным портом который не меняется, там обмениваются информацией. Почему порты меняются? Ресурс этот ограниченный и его может занять какой-то другой компьютер из вашей под сети. Хотя обычно на несколько часов он ваш. У TCP сложнее там есть сообщения подтверждения которые мешают такой схеме. Там надо конектится на уже доступный порт. Но благо в том что за частую NAT не проверяет обратные вхождения по IP!!! Им главное совпадение на портов. Тут как раз без стороннего сервера не обойтись. Клиент1 IP1 port1 Клиент2 IP2 port2 сервер IPs nat1 внешний ип IPn1 nat2 внешний ип IPn2 IP1:port1 шлет сообщение на сервер IPs:port3 IP2:port2 шлет сообщение на сервер IPs:port3 где они объмениваются информацией потом ip1:port1 шлет сообщение на ips:port2 Ip2:port2 шлет сообщение на nat1:port1 Нат пропустит сообщение, в большинстве случаев. Это как-раз и сделано для удобства пользователей. К примеру VoIP используют stun сервера. Протокол stun описан в RFC и используется для изучения различных типов NAT. Даже если NAT фильтрует сообщения по TCP, а UDP закрыт то велика возможность, что есть pnp. pnp это протокол в котором разрешено договориться с устройством nat сервером о том чтобы тот открыл порты. Суммирая всю информацию. Есть куча возможностей которые позволяют преодолеть NAT. Даже если NAT целиком закрыт, то можно сделать следующее поднять IPv6 он будет работать даже на односторонней связи. Когда клиент будет переодически опрашивать релей сервер для получения и отправки пакета. А вот IPv6 уже не отфильтруют натом.
Больше всего мне нравится идея с ipv6. Но нет возможности использовать дополнительный выделенный сервер. Возможно ли организовать взаимодействие двух компьютеров(под натом) через ipv6 при условии, что эти самые компьютеры используют ipv6 через туннель(sixxs.net, например)?