Новичок
Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016
Репутация: нет Всего: нет
|
Пишу программу для удаленного администрирования по сети. Сервер запускается на моем компьютере, который находится за НАТом, клиент может быть где угодно. Для подключения к себе использую Dynamic DNS. Проброс портов настроил так: (роутер D-Link DIR-620, админка с темным дизайном) Мой сервер работает на порту 666, к нему делается проброс через порт 55000 из внешней сети. Исходники клиента и сервера: Сервер: Код | #include <WinSock2.h> #include <Ws2tcpip.h> #include <Windows.h> #include <stdio.h> #include <stdint.h>
#pragma comment(lib, "ws2_32.lib")
#define LOCAL_PORT 666 #define DEFAULT_PORT "666" /* Must be the same as PORT */ #define MAX_CONNECTIONS 10
BOOL WINAPI InitWinSock(); void WINAPI FormatError(DWORD error); SOCKET WINAPI BindSocket(uint16_t port); DWORD WINAPI HandleConnection(LPVOID sock); void WINAPI PrintClientInfo(sockaddr_in *addr);
int main(int argc, char *argv[]) { SOCKET server; SOCKET client; DWORD ThreadID; sockaddr_in client_addr; int addr_len = sizeof(client_addr);
if (InitWinSock()) { server = BindSocket(LOCAL_PORT); if (listen(server, MAX_CONNECTIONS) == SOCKET_ERROR) { FormatError(WSAGetLastError()); WSACleanup(); return -1; }
printf("Acception loop\n"); while (TRUE) { client = accept(server, (struct sockaddr *)&client_addr, &addr_len); printf("Accepted!\n"); if (client != INVALID_SOCKET) { PrintClientInfo(&client_addr); CreateThread(NULL, 0, HandleConnection, &client, NULL, &ThreadID); } } WSACleanup(); } }
BOOL WINAPI InitWinSock() { WSADATA wsadata; if (FAILED(WSAStartup(MAKEWORD(2, 2), &wsadata))) { FormatError(WSAGetLastError()); return FALSE; } return TRUE; }
void WINAPI FormatError(DWORD errCode) { char error[1000]; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(), MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), error, sizeof(error), NULL); printf("\nError: %s\n", error); }
SOCKET WINAPI BindSocket(uint16_t port) { SOCKET sock = INVALID_SOCKET; sockaddr_in local_addr;
sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { FormatError(WSAGetLastError()); } else { RtlZeroMemory(&local_addr, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(port); local_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) == SOCKET_ERROR) { FormatError(WSAGetLastError()); } else { printf("Server running on port %u address %s...\n", local_addr.sin_port, inet_ntoa(local_addr.sin_addr)); } }
return sock; }
DWORD WINAPI HandleConnection(LPVOID sock) { SOCKET client; HANDLE hFile = NULL; char buffer[200]; int recv_bytes = 0; DWORD bytes_written = 0;
printf("Handle connection...\n");
client = *(SOCKET *)sock; char msg[] = "hello"; send(client, msg, sizeof(msg), 0);
shutdown(client, SD_BOTH); closesocket(client);
printf("Connection closed\n");
return 0; }
void WINAPI PrintClientInfo(sockaddr_in *addr) { char hostname[NI_MAXHOST];
getnameinfo((struct sockaddr *)addr, sizeof(*addr), hostname, sizeof(hostname), NULL, 0, 0); printf("+ %s [%s] new connection\n", hostname, inet_ntoa(addr->sin_addr)); }
|
Клиент: Код | #include <Ws2tcpip.h> #include <stdio.h> #include <stdint.h> #include "auth.h" #include "error.h"
#pragma comment(lib, "ws2_32.lib")
#define LOCAL_PORT 667 #define REMOTE_HOST "имя.ddns.net" #define REMOTE_PORT 55000 #define DEFAULT_PORT "55000" /* Must be the same as REMOTE_PORT */ #define MAX_CONNECTIONS 10
SOCKET WINAPI BindSocket(uint16_t port); DWORD WINAPI HandleConnection(LPVOID sock); void WINAPI BackConnect(char *hostname);
int main(int argc, char *argv[]) { WSADATA wsadata; SOCKET server; SOCKET client; DWORD ThreadID; sockaddr_in client_addr; int addr_len = sizeof(client_addr);
if (FAILED(WSAStartup(MAKEWORD(2, 0), &wsadata))) { FormatError(WSAGetLastError()); } else { server = BindSocket(LOCAL_PORT); if (listen(server, MAX_CONNECTIONS) == SOCKET_ERROR) { FormatError(WSAGetLastError()); WSACleanup(); return -1; }
printf("Listening port %d...\n", LOCAL_PORT);
BackConnect(REMOTE_HOST); while (TRUE) { client = accept(server, (struct sockaddr *)&client_addr, &addr_len); if (client != INVALID_SOCKET) { CreateThread(NULL, 0, HandleConnection, &client, NULL, &ThreadID); } } WSACleanup(); } }
SOCKET WINAPI BindSocket(uint16_t port) { SOCKET sock = INVALID_SOCKET; sockaddr_in local_addr;
sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { FormatError(WSAGetLastError()); } else { RtlZeroMemory(&local_addr, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(port); local_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) == SOCKET_ERROR) { FormatError(WSAGetLastError()); } else { printf("Server running...\n"); } }
return sock; }
BOOL MyCmp(char *s1, char *s2) { for (int i = 0; *s1 && *s2; s1++, s2++) if (*s1 != *s2) return FALSE; return TRUE; }
DWORD WINAPI HandleConnection(LPVOID sock) { SOCKET client = INVALID_SOCKET; HANDLE hFile = NULL; char buffer[200]; DWORD bytes_written = 0; int auth_flag = 0;
client = *(SOCKET *)sock;
SendData(client, "command>");
while (TRUE) { ZeroMemory(buffer, sizeof(buffer)); int recv_bytes = recv(client, buffer, sizeof(buffer), 0); if (recv_bytes > 0) { if (MyCmp(buffer, "exit")) { printf("command: exit\n"); break; } else if (MyCmp(buffer, "help")) { printf("command: help\n"); SendData(client, "\thello\r\n"); } else if (MyCmp(buffer, "auth")) { auth_flag = AuthProc(client); } } else break;
SendData(client, "command>"); }
closesocket(client); printf("Connection closed\n");
return 0; }
void WINAPI BackConnect(char *hostname) { struct addrinfo *result = NULL; struct addrinfo *ptr = NULL; struct addrinfo hints; struct sockaddr_in *remote_addr_ptr = NULL; SOCKET sock = INVALID_SOCKET;
ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP;
getaddrinfo(hostname, DEFAULT_PORT, &hints, &result); ptr = result;
if (ptr->ai_family == AF_INET) { remote_addr_ptr = (struct sockaddr_in *)ptr->ai_addr; printf("IPv4 address %s, port %u\n", inet_ntoa(remote_addr_ptr->sin_addr), remote_addr_ptr->sin_port);
sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (sock == INVALID_SOCKET) { FormatError(WSAGetLastError()); } else { //remote_addr_ptr->sin_addr.s_addr = inet_addr("127.0.0.1"); remote_addr_ptr->sin_port = htons(REMOTE_PORT); if (connect(sock, (struct sockaddr *)remote_addr_ptr, sizeof(*remote_addr_ptr)) == SOCKET_ERROR) { printf("Connection to %s port %u failed\n", inet_ntoa(remote_addr_ptr->sin_addr), remote_addr_ptr->sin_port); FormatError(WSAGetLastError()); } else { char szComputerName[MAX_PATH]; DWORD dwSize = MAX_PATH / sizeof(TCHAR);
GetComputerNameA(szComputerName, &dwSize); SendData(sock, szComputerName); } closesocket(sock); } } }
|
Проблема возникает при соединении клиента с сервером. Сейчас и клиент и сервер находятся на моем компютере несмотря на то, что соединение происходит через Dynamic DNS. Вот скрины: Это на сервере Это на клиенте Почему на сервере появляется три сообщения о подключении, если клиент создает только одно? Почему на клиенте функция connect завершается с ошибкой, а WSAGetLastError говорит, что операция завершена успешно? Это сообщение отредактировал(а) Aoizora - 11.12.2016, 13:57
|