Бывалый

Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул
Репутация: нет Всего: нет
|
Клиент-серверное приложение. В общем, надо сделать примитив синхронизации - канал. Решил сделать так: 1. На клиенте создаётся канал, он отправляет команды на сервер, там создаётся новый примитив канал (у меня уже нормальный канал, который для межпроцессорного взаимодействия предназначен). В общем клиенты посылают команды и получают ответы сервера. Если начал делать в корне не верно, поправьте меня - первый раз в жизни с сокетами дело имею. Итак: клиент создаёт сокет, соединяется с сервером - тут всё нормально. Но вот функция send() возвращает код ошибки и соответсвенно ничего серверу не посылает. Не знаю почему. На первый взгляд, всё до этого момента идёт нормально и код этот везде до этой функции send() просто скопирован из msdn (в ней пример есть, конечно же, рабочий). УТОЧНЮ: send() возвращает SOCKER_ERROR, а дальшейший вызов WSAGetLastError() возвращает код 10014 (WSAEFAULT). Собственно код: На стороне клиента: | Код | try { NetworkChannel *ch = new NetworkChannel(STANDARD_CHANNEL_DEPTH, STANDARD_CHANNEL_TIMEOUT, L"testch", "127.0.0.1", DEFAULT_PORT);
delete ch; } catch(int err) { printf("exception in NetworkChannel constructor: %d\n", err); }
_getch(); return 0;
|
1. Конструктор канала: | Код | NetworkChannel::NetworkChannel(int max_depth, int def_timeout, wchar_t *name, char *server_ip, char *server_port) { // Создаём новый канал socket = OpenSocket(server_ip, server_port); if(socket == INVALID_SOCKET) throw 0;
// отправляем запрос на сервер int iResult; ChannelCreateStruct ch; ch.max_depth = max_depth; ch.def_timeout = def_timeout; ch.name_length = wcslen(name);
// запросим создание нового канала printf("CHANNEL_OPEN_COMMAND = %d", (int)CHANNEL_OPEN_COMMAND); printf("sizeof(int) = %d\tsizeof(CHANNEL_OPEN_COMMAND) = %d\n", (int)sizeof(int), sizeof((char*)((int)CHANNEL_OPEN_COMMAND)));
// ВОТ ЭТОТ SEND() ВОЗВРАЩАЕТ ОШИБКУ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! iResult = send(socket, (char*)((int)CHANNEL_OPEN_COMMAND), (int)sizeof(int), 0); // !!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if(iResult == SOCKET_ERROR) { printf("Network channel: socket error on CHANNEL_OPEN_COMMAND send\n"); closesocket(socket); WSACleanup(); throw 1; } ... // другие запросы }
|
2. Функция OpenSocket: | Код | SOCKET OpenSocket(char *ip, char *port) { int iResult; WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); _getch(); return INVALID_SOCKET; }
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(ip, port, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed: %d\n", iResult); WSACleanup(); _getch(); return INVALID_SOCKET; }
// 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("Error at socket(): %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); _getch(); return INVALID_SOCKET; }
// 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(); _getch(); return INVALID_SOCKET; }
return ConnectSocket; }
|
Серверный код: | Код | int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; int iResult;
// Инициализировать Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if(iResult != 0) { printf("WSAStartup failed: %d\n", iResult); _getch(); return 1; }
struct addrinfo *result = NULL, *ptr = NULL, 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;
// Resolve the local address and port to be used by the server iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed: %d\n", iResult); WSACleanup(); _getch(); return 1; }
SOCKET ListenSocket = INVALID_SOCKET;
// Create a SOCKET for the server to listen for client connections ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); _getch(); return 1; }
// Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); _getch(); return 1; }
if ( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR ) { printf( "Error at listen(): %ld\n", WSAGetLastError() ); closesocket(ListenSocket); WSACleanup(); _getch(); return 1; }
SOCKET ClientSocket;
vector<HANDLE> handle; //do //{ ClientSocket = INVALID_SOCKET;
// Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); _getch(); return 1; } // создаём новый поток, где и обрабатываем сокет HANDLE h = CreateThread(NULL, 0, &ServerWork, (void*)ClientSocket, 0, NULL); handle.push_back(h);
//HANDLE server_handle = (HANDLE)_beginthreadex(NULL, 0, &ServerWork, (void*)ClientSocket, 0, NULL);
if(_kbhit()) { if(_getch() == 'x') ;//break; } //}while(1);
for(vector<HANDLE>::iterator i = handle.begin(); i != handle.end(); i++) { WaitForSingleObject((HANDLE)*i, INFINITE); CloseHandle(*i); }
_getch(); return 0; }
DWORD WINAPI ServerWork(LPVOID socket) { SOCKET ClientSocket = (SOCKET)socket;
char *recvbuf; int iSendResult; int recvbuflen = (int)sizeof(int); int iResult;
// Взяли команду recvbuf = new char[recvbuflen]; printf("recvbuflen = %d\tsizeof(recvbuf) = %d\n", recvbuflen, sizeof(recvbuf)); iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); printf("recvbuf = "); puts(recvbuf); if(iResult <= 0) goto shutdown_socket; int command; memcpy(&command, recvbuf, sizeof(int)); printf("command = %d", command);
. . . // обработка следующих запросов }
|
Кроме того, я проверял, чтобы размеры буфера были одинаковые и там и там, кроме того указывал длину (int)sizeof(int)+1, тоже ничего не изменило. Это сообщение отредактировал(а) Arks - 30.1.2009, 23:09
|