Новичок
Профиль
Группа: Участник
Сообщений: 3
Регистрация: 23.8.2007
Репутация: нет Всего: нет
|
Я написал простенький сервер, но в нем одна проблемка, он не хочет отправлять пакеты клиентам, клиенты коннектятся, могут отправлять пакеты на сервер, сервер все видит. Сервер построен с использованием порта завершения. Как мне кажется проблема в функции SendMessageNCP() , а именно в АПИ функции WSASend() Очень жду ответов, заранее спасибо. Вот исходники Сам класс CompletionPortКод | // NetCompletionPort.h: interface for the NetCompletionPort class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_NETCOMPLETIONPORT_H__48039904_FFB7_44AA_AA5C_EE318620C63D__INCLUDED_) #define AFX_NETCOMPLETIONPORT_H__48039904_FFB7_44AA_AA5C_EE318620C63D__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <stdio.h> #include <conio.h> #include <malloc.h> #include <Winsock2.h> #include <list> // Используем STL #include "NetDefine.h" #pragma comment (lib,"ws2_32.lib") // Линковка библиотеки ws2_32.lib using namespace std; // Использовать пространство имен std
class NetCompletionPort { public: int net_error; HANDLE hCp; // описатель порта DWORD ThreadId; // ИД потока сервера HANDLE hThread; // хендл потока сервера SOCKET server_sock; NetCompletionPort(); void Start(); virtual ~NetCompletionPort();
};
#endif // !defined(AFX_NETCOMPLETIONPORT_H__48039904_FFB7_44AA_AA5C_EE318620C63D__INCLUDED_) ------------------------------------------------------------------------------------------------------ // NetCompletionPort.cpp: implementation of the NetCompletionPort class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "NetCompletionPort.h"
DWORD WINAPI ServerPool(HANDLE hp); void Print(const char * str);
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
NetCompletionPort::NetCompletionPort() { WORD wVersionRequested; // Запрашиваемая версия WSADATA wsaData; // Структура инф-ции о сокетах int err;
//Инициализация библиотеки ws2_32.dll wVersionRequested=MAKEWORD(2,2); err=WSAStartup(wVersionRequested,&wsaData); if(err==SOCKET_ERROR) { net_error=-1; WSACleanup(); // Завершение работы return; } //Создаем порт завершения hCp=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); if(hCp==NULL) { net_error=-1; WSACleanup(); // Завершение работы return; } // Задаем параметры для прослушивающего сокета сервера server_sock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,NULL, WSA_FLAG_OVERLAPPED); if(server_sock==INVALID_SOCKET) { net_error=-1; WSACleanup(); //Завершение работы с сокетами return; } else { // Используем ранее созданный порт завершения if(CreateIoCompletionPort((HANDLE)server_sock,hCp,0,0)==NULL) { net_error=-1; WSACleanup(); //Завершение работы return; } } //Заполняем структуру адреса и подключаем сокет к коммуникационной среде SOCKADDR_IN sinServer; sinServer.sin_family = AF_INET; sinServer.sin_port = htons(gm_PORT_SERVER); sinServer.sin_addr.s_addr = INADDR_ANY; err = bind( server_sock,(LPSOCKADDR)&sinServer,sizeof(sinServer) ); if(err==-1) { net_error=-1; WSACleanup(); //Завершение работы return; } //Создаем очередь для ожидания запросов от клиентов на соединение err = listen(server_sock, SOMAXCONN); if(err==-1) { net_error=-1; WSACleanup(); // Завершение работы return; }
}
NetCompletionPort::~NetCompletionPort() { WSACleanup(); }
void NetCompletionPort::Start() { //Cоздаем рабочий поток для обслуживания сообщений от порта завершения hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerPool,hCp,0, &ThreadId); Print("СЕРВЕР запущен\n"); }
|
Класс коннектовКод | // NetConnection.h: interface for the NetConnection class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_NETCONNECTION_H__71F045AA_B2BE_4DD6_83C8_2B6158FAB442__INCLUDED_) #define AFX_NETCONNECTION_H__71F045AA_B2BE_4DD6_83C8_2B6158FAB442__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <stdio.h> #include <Winsock2.h> #include "NetDefine.h"
struct NetConnection :public OVERLAPPED { public: NetConnection(); virtual ~NetConnection();
int client_number; // ═юьхЁ ъышхэЄр SOCKET sock_handle; // ╤юъхЄ ъышхэЄр char * buffer; // ┴єЇхЁ ёююс∙хэшщ enum { op_type_send, // ╧юё√ыър op_type_recv // ╧Ёшхь }op_type; };
#endif // !defined(AFX_NETCONNECTION_H__71F045AA_B2BE_4DD6_83C8_2B6158FAB442__INCLUDED_) --------------------------------------------------------------------------------------------------------------------------------------- // NetConnection.cpp: implementation of the NetConnection class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "NetConnection.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
NetConnection::NetConnection() {
}
NetConnection::~NetConnection() {
}
|
Основная программаКод | // Макроподстановки // NetConnection.h: interface for the NetConnection class. // //////////////////////////////////////////////////////////////////////
#if !defined(NetDefine) #define NetDefine
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#define gm_MAX_MESSAGE_SIZE 128 // размер буффера сообщения #define gm_PORT_SERVER 28912 // номер порта сервера #define gm_MAX_CONNECTION 1000 // максимальное количество подключенных
static int ClientCount; // Счетчик клиентов
#endif // !NetDefine ----------------------------------------------------- MAIN ---------------------------------------------------------------- // NetDriver.cpp : Defines the entry point for the console application. //
#include "stdafx.h" #include "NetCompletionPort.h" #include "NetConnection.h" #include "NetDefine.h" #include <list.h>
void SendMessageNCP(SOCKET sock_handle, char *buffer, unsigned long bytes );
static list <SOCKET> ClientList; // Список клиентов
void Print(const char * str) { char buffer[128]; strcpy(buffer,str); CharToOem(buffer,buffer); printf(buffer); }
DWORD WINAPI ServerPool(HANDLE hp) { int err; // Возвращяемое значение unsigned long bytes; // Кол-во байтов unsigned long key; // Значение, асоциированное с хендлом порта char buffer[128]; // Буфер для сообщений LPOVERLAPPED overlapped; // Структура асинхронного I/O HANDLE hport=hp; // Дескриптор порта DWORD flags; // Флаги ф-ции WSARecv() while(true) { // Получаем информацию о завершении операции if(GetQueuedCompletionStatus(hport, &bytes, &key, &overlapped, INFINITE)) { // Операция завершена успешно NetConnection * ncon = (NetConnection*)overlapped; // Определяем тип завершенной операции и выполняем соответствующие действия switch(ncon->op_type) { //Завершена отправка данных case NetConnection::op_type_send: delete [] ncon->buffer; delete ncon; break; //Завершен приём данных case NetConnection::op_type_recv: if(!bytes) { //Соединение с данным клиентом закрыто ClientList.remove(ncon->sock_handle); closesocket(ncon->sock_handle); Print("Клиент №"); printf("%d",ncon->client_number); Print(" отключился, активных клиентов "); printf("%d\n",ClientList.size()); break; } ncon->buffer[bytes]='\0'; strcpy(buffer,"От клиента № %d получено сообщение %s\n"); CharToOem(buffer,buffer); printf(buffer,ncon->client_number,ncon->buffer);
SendMessageNCP(ncon->sock_handle, "Test",4);
unsigned long b; WSABUF buf; buf.buf = ncon->buffer; buf.len = gm_MAX_MESSAGE_SIZE; flags=0; //b=0; err=WSARecv(ncon->sock_handle, &buf, 1, &b, &flags, ncon, 0); if(!err) { Print("Ошибка функции WSARecv"); } // } } else { if(!overlapped) { // Ошибка с портом // Закрываем все сокеты, закрываем порт, очищаем список //for(list<SOCKET>::iterator i=ClientList.begin();i!=ClientList.end();i++) //{ // closesocket(*i); //} //ClientList.clear(); //strcpy(buffer,"Ошибка порта № %d, сервер завершает работу\n"); //CharToOem(buffer,buffer); //printf(buffer,GetLastError()); //getch(); //exit(0); } else { //Закрываем соединение с клиентом closesocket(((NetConnection*)overlapped)->sock_handle); ClientList.remove(((NetConnection*)overlapped)->sock_handle); strcpy(buffer,"Клиент № %d отключился, активных клиентов %d\n"); CharToOem(buffer,buffer); printf(buffer,((NetConnection*)overlapped)->client_number,ClientList.size()); } } } return 0; }
int main(int argc, char* argv[]) { NetCompletionPort * netCP = new NetCompletionPort; DWORD flags; // Флаги ф-ции WSARecv int err;
if (netCP ->net_error != -1 ) {} else { Print("Произошла ошибка при создании сервера!\n"); return 0; }
netCP->Start();
ClientCount=0;
// Вечный цикл while(true) { //Принимаем запрос от программы-клиента на установление связи SOCKADDR_IN sinClient; int lenClient=sizeof(sinClient); SOCKET client = accept(netCP->server_sock,(struct sockaddr*)&sinClient, &lenClient); CreateIoCompletionPort((HANDLE)client,netCP->hCp,0,0); // Добавили клиента в список ClientList.insert(ClientList.end(),client); // Создаем структуру коннекта NetConnection *ncon = new NetConnection; // теперь заполняем ее ncon->sock_handle = client; ncon->op_type = NetConnection::op_type_recv; ncon->buffer = new char[gm_MAX_MESSAGE_SIZE]; ncon->hEvent = 0; ncon->client_number=++ClientCount;
Print("Подключился клиент №"); printf("%d",ClientCount); printf("\n");
// Вызываем функцию чтения unsigned long b; WSABUF buf; buf.buf = ncon->buffer; buf.len = gm_MAX_MESSAGE_SIZE; flags=0; err=WSARecv(ncon->sock_handle, &buf, 1, &b, &flags, ncon, 0); if(!err) { Print("Ошибка функции WSARecv"); delete [] ncon->buffer; delete ncon; }
SendMessageNCP(client, "OK",2); }
delete netCP; Print("СЕРВЕР закрыт!\n");
return 0; }
void SendMessageNCP(SOCKET sock_handle, char *buffer, unsigned long bytes ) { char buf_m[128]; NetConnection * nconSend = new NetConnection; nconSend->sock_handle = sock_handle; nconSend->op_type = NetConnection::op_type_send; nconSend->buffer = new char[bytes+1]; memcpy(nconSend->buffer, buffer, bytes); nconSend->buffer[bytes]='\0'; unsigned long b;
WSABUF buf; buf.buf = nconSend->buffer; buf.len = bytes;
WSASend(nconSend->sock_handle,&buf,1,&b, 0, nconSend, 0);
return; }
|
Присоединённый файл ( Кол-во скачиваний: 12 )
NetDriver.rar 4,82 Kb
|