Witam! Na poczatek wrzucam kod:
SERWER:
struct SPakiet
{
int cmd;
int dlpakietu;
};
class CSerwer
{
private:
WSADATA wsd;
int conn_port;
SOCKET sListen;
int Transfer_Error;
std::vector<SOCKET> SockTab;
DWORD ListenThread();
DWORD SocketThread();
int sendall( int s, char * buf, int len );
public:
static DWORD WINAPI StartListenThread(CSerwer* srv) { return srv->ListenThread(); };
static DWORD WINAPI StartSocketThread(CSerwer* srv) { return srv->SocketThread(); };
CSerwer():Transfer_Error(-1) {SockTab.push_back(*(new SOCKET));};
~CSerwer();
bool Init(int port);
bool SendCMD(int SockIndex, int iCMD, char* cmd);
};
...
...
int CSerwer::sendall( int s, char * buf, int len )
{
int total = 0;
int bytesleft = len;
int n;
while( total < len ) {
n = send( s, buf + total, bytesleft, 0 );
if( n == - 1 ) { break; }
total += n;
bytesleft -= n;
}
return total<len?- 1: 1;
}
bool CSerwer::Init(int port)
{
conn_port=port;
sockaddr_in local;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
#ifdef DEBUG
logger.LogError("Blad przy starcie WSAStartup. kod bledu: %d", WSAGetLastError());
#endif
return 0;
}
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sListen == SOCKET_ERROR)
{
#ifdef DEBUG
logger.LogError("Blad przy tworzeniu socketu. kod bledu: %d", WSAGetLastError());
#endif
return 0;
}
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons((u_short)conn_port);
if (bind(sListen, (sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
#ifdef DEBUG
logger.LogError("Blad przy ustawianiu socketu. kod bledu: %d", WSAGetLastError());
#endif
return 0;
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CSerwer::StartListenThread, this, 0, NULL);
return true;
}
DWORD CSerwer::ListenThread()
{
sockaddr_in client;
listen(sListen, SOMAXCONN);
int iAddrSize = sizeof(client);
while(1)
{
SockTab[SockTab.size()-1] = accept(sListen, (sockaddr *)&client, &iAddrSize);
if (SockTab[SockTab.size()-1] == INVALID_SOCKET)
{
#ifdef DEBUG
logger.LogInfo("Nie mozna zaakceptowac uzytkownika. kod bledu: %d ", WSAGetLastError());
#endif
continue;
}
#ifdef DEBUG
logger.LogInfo("Zaakceptowano polaczenie z uzytkownikiem");
#endif
SockTab.push_back(*(new SOCKET));
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CSerwer::StartSocketThread, this, 0, NULL);
}
return 1;
};
DWORD CSerwer::SocketThread()
{
int SockIndex=SockTab.size()-2;
SPakiet pakiet;
//Sprawdzanie poprawnosci klienta --------------------------------------------------------------------------------------
if(recv(SockTab[SockIndex], reinterpret_cast<char*>(&pakiet), sizeof(pakiet), MSG_WAITALL)<=0 || pakiet.cmd!=WELCOME)
{
#ifdef DEBUG
logger.LogError("Odrzucono polaczenie z klientem(brak odpowiedzi WELCOME). kod bledu: %d", WSAGetLastError());
#endif
return 1;
}
// PO wywolaniu sendall na kliencie pokazuje sie error 10045 i program wisi//
if(!sendall(SockTab[0], reinterpret_cast<char*>(&pakiet), sizeof(pakiet)) )
{
#ifdef DEBUG
logger.LogInfo("Blad! Czesc pakietu nie zostala wyslana!! kod bledu: ", WSAGetLastError());
#endif
}
//Sprawdzanie poprawnosci klienta ---------------------------------------------------------------------------------------
// PO wywolaniu sendall na kliencie pokazuje sie error 10045 i program wisi//
while(1)
{
if(recv(SockTab[SockIndex], reinterpret_cast<char*>(&pakiet), sizeof(pakiet), MSG_WAITALL)<=0)
{
...
}
KLIENT
class CServer
{
private:
SOCKET sClient;
std::string CServer::exec_CMD(char* cmd);
WSADATA wsd;
public:
bool init(char adrIP[128], int port);
void CMD_Proc();
~CServer();
};
bool CServer::init(char adrIP[128], int port)
{
sockaddr_in server;
hostent *host = NULL;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
#ifdef DEBUG
logger.LogInfo("Blad przy WSAStartup. kod bledu: %d", WSAGetLastError());
#endif
return false;
}
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET)
{
#ifdef DEBUG
logger.LogError("Blad przy tworzeniu socketu. kod bledu: %d", WSAGetLastError());
#endif
return false;
}
server.sin_family = AF_INET;
server.sin_port = htons((u_short)port);
server.sin_addr.s_addr = inet_addr(adrIP);
if (server.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(adrIP);
if (host == NULL)
{
#ifdef DEBUG
logger.LogError("Blad przy przeksztalcaniu adresu na IP. kod bledu: %d", WSAGetLastError());
#endif
return false;
}
CopyMemory(&server.sin_addr, host->h_addr_list[0], host->h_length);
}
if (connect(sClient, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
#ifdef DEBUG
logger.LogError("Blad przy probie polaczenia. kod bledu: %d", WSAGetLastError());
#endif
return false;
}
SPakiet pak;
pak.cmd=WELCOME;
sendall(sClient, reinterpret_cast<char*>(&pak), sizeof(pak));
pak.cmd=0;
recv(sClient, reinterpret_cast<char*>(&pak), sizeof(pak), 0);
if(pak.cmd!=WELCOME)
return false;
#ifdef DEBUG
logger.LogInfo("Polaczono!");
#endif
return true;
}
void CServer::CMD_Proc()
{
SPakiet pakiet;
while(1)
{
//TUTAJ ZRYWA POLACZENIE, przynajmniej tak wychodzi z tego warunku//
if(recv(sClient, reinterpret_cast<char*>(&pakiet), sizeof(pakiet), MSG_WAITALL)<=0)
{
#ifdef DEBUG
logger.LogError("Zerwano polaczenie z klientem. kod bledu: %d", WSAGetLastError());
#endif
return;
}
switch(pakiet.cmd)
...
...
}
Kupa kodu, ale chyba bez niego nikt nie bylby w stanie mi pomoc. Problem polega na tym ze program dziala w 100% poprawnie na windows 7 a na win xp zrywa polaczenie - recv zwraca -1 w kliencie w CMD_Proc(), error 10045. Rece mi opadaja bo nie mialem jeszcze takiej sytuacji, patrzylem czy ten error 10045 nie pochodzi z poprzednich wywolan funkcji i na pewno tak nie jest, patrzylem czy gdzies przypadkiem nie modyfikuje socketu klienta - tez wykluczone. Moze zle inicjalizuje WinSock? Dodam, ze tam gdzie recv() zwraca -1 u klienta, w serwerze funkcja sendall mowi ze caly pakiet zostal wyslany.
Reasumujac, nie wiem czy klient czy serwer(ale raczej klient, skoro serwer z klientem na win 7 dziala ok) zrywa polaczenie zaraz po wyjsciu z Init() - po sprawdzeniu poprawnosci klienta czyli wyslaniu i odebraniu WELCOME.
Prosze zeby ktos ogarniety w WinSock rzucil na to okiem, bo po paru godzinach wysiadam. Dzieki z gory :)