Winsock Client/Server- Inspiegabili errori 10053 / 10054

di il
4 risposte

Winsock Client/Server- Inspiegabili errori 10053 / 10054

Ciao a tutti,

mi trovo a scrivere sul forum dopo una settimana di tentativi... diciamo che ho cercato di non disturbare

Sto combattendo con la libreria winsock su Windows Xp e Windows 7.

Innanzi tutto ho scritto una semplice classe TcpSocket per lavorare ad oggetti con le funzioni di winsock.

Per effettuare i vari test di funzionamento e stress ho scritto inoltre due mini applicazioni, un client ed un server, che altro non fanno che mandarsi reciprocamente 10 bytes in modo alternato.


Sulla mia macchina con Windows Xp SP3, i due programmi lavorano senza problemi fino al ciclo 65535 ( non credo sia un caso questo numero...): a quel punto il client ottiene in lettura un errore WSAECONNABORTED (10053) causando la chiusura del socket, mentre il server ottiene un WSAECONNRESET (10054).

Su Windows 7 lo stesso identico problema avviene ben prima, ovvero al ciclo 16

Non capisco come possa lo stesso programma, connesso in localhost, riscontrare un problema di networking, costante a pari condizioni, ma diverso da OS ad OS.

Ho provato anche a far girare le due applicazioni alternatamente su due pc diversi ottenendo gli stessi risultati. Osservando con wireshark il traffico di rete, è possibile vedere che la macchian dove si verifica il WSAECONNABORTED invia un RST tcp senza un motivo apperente.

Vi allego i due screenshot delle due command line.

Se risulta utile, posso postare anche l'implentazione della classe TcpSocket.


Sono nelle vostre mani!
Vi ringrazio anticipatamente per l'aiuto!

Gianluca


This is the server code:

#include "stdafx.h"
#include "TcpSocket.h"

#define  listenPort 9559

int _tmain(int argc, _TCHAR* argv[])
{

	printf("TcpServerTest Started\n\n");
	

	//STARTING LISTENING SERVER
	TcpSocket socket;
	printf(("Starting listening on port " + to_string((long long)listenPort) + " ... ").c_str());
	if(!socket.Listen("", listenPort)){
		printf(("FAILURE\nError: " + socket.errorString() + "\n").c_str());
		Sleep(5000);
		return false;
	}
	printf("OK\n");

	//WAITING FOR INCOMING CONNECTION
	printf("Waiting for incoming connection...");
	TcpSocket * client = socket.Accept();
	if(!client->IsValid()){
		printf(("FAILURE\nError: " + socket.errorString() + "\n").c_str());
		Sleep(5000);
		return false;
	}


	char * outMsg = new char[10];
	int outSize = 10;
	int readData;
	//STARTING CICLE
	for(long long i = 1; i > 0; i ++){
		//Creating & sending out message
		if(!client->Write(outMsg, 10)){
			printf(("WRITING FAILURE\nError: " + client->errorString() + "\n").c_str());
			Sleep(500000);
			return false;
		}
		//Reading reply
		char * incoming = client->Read(readData);
		if(readData == 0){
			printf("\nConnection closed\n");
			break;
		}
		if(readData == SOCKET_ERROR){
			printf(("FAILURE\nError: " + client->errorString() + "\n").c_str());
			Sleep(5000000);
			return false;
		}
		delete incoming;
		printf(("Cicle " + to_string(i) + " complete\n").c_str());
	}

	delete outMsg;
	Sleep(5000);
	return 0;
	
}



And This is the client code:


#include "stdafx.h"
#include "TcpSocket.h"

#define  connectPort 9559

int _tmain(int argc, _TCHAR* argv[])
{
		printf("TcpClientTest Started\n\n");
	

	//STARTING LISTENING SERVER
	TcpSocket socket;
	printf(("Connecting on port " + to_string((long long)connectPort) + " ... ").c_str());
	if(!socket.Connect("127.0.0.1", connectPort)){
		printf(("FAILURE\nError: " + socket.errorString() + "\n").c_str());
		Sleep(5000);
		return false;
	}
	printf("OK\n");


	int outSize = 10;
	char * outMsg = new char[10];
	//STARTING CICLE
	for(long long i = 1; i > 0; i ++){
		//Reading input message
		int readData;
		char * incoming = socket.Read(readData);
		if(readData == 0){
			printf("\nConnection closed\n");
			break;
		}
		if(readData == SOCKET_ERROR){
			printf(("FAILURE\nError: " + socket.errorString() + "\n").c_str());
			Sleep(5000000);
			return false;
		}
		delete incoming;
		//Sending reply message
		if(!socket.Write(outMsg, 10)){
			printf(("WRITING FAILURE\nError: " + socket.errorString() + "\n").c_str());
			Sleep(500000);
			return false;
		}
		printf(("Cicle " + to_string(i) + " complete\n").c_str());
	}
	delete outMsg;
	Sleep(5000);
	return 0;
}



Last the TcpSocket header:
#pragma once
#pragma comment(lib, "Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#include "TcpSocket.h"


#include <string>
using namespace std;

class TcpSocket
{
public:
	TcpSocket(void);
	~TcpSocket(void);

	void		Close();
	bool		Connect(char * address, int port);
	bool 		Write (char* data, int length);
	bool  		Write (wchar_t* data, int length);
	char *	    Read(int & readBytes);
	void		SetSocket(int socket) { sock = socket; };
	int			Socket() { return sock; };
	void		SetBufferSize(unsigned int size);
	bool		Listen(char * address, int port);
	TcpSocket * Accept();
	bool		isBlocking(){ return blocking_socket; };
	bool		setBlocking(bool);
	bool		hasReadyData();
	bool		IsValid(){ return sock != INVALID_SOCKET; };
	string  errorString(){ return errorMsg; };
	int			lastErrorCode(){ return errorCode; };
	//int		SendData			(int sock, char * ptr, int length);
static string   getErrorMessage(int errorCode);

private:
	int sock;
	int errorCode;
	string errorMsg;

	int  bufferSize;
	char * buffer;
	int  readyBytes;

	bool blocking_socket;

	fd_set * readSet,
		   * writeSet,
		   * exceptionSet;
	timeval * timeout;

};


Allegati:
7613_bf177dfd61d6c1eacd773226db97c626.jpg
7613_bf177dfd61d6c1eacd773226db97c626.jpg

7613_78c9c362dd0f49f265107fc8347bd685.jpg
7613_78c9c362dd0f49f265107fc8347bd685.jpg

4 Risposte

  • Re: Winsock Client/Server- Inspiegabili errori 10053 / 10054

    Un header che include se stesso?
    in TcpSocket.h
    
    #include "TcpSocket.h"
    
    ogni new [] deve avere il corrispettivo delete [] e non solo delete.
    Manca il listato del TcpSocket.cpp.
    Io non so molto di network programming ma almeno dal lato C++ hai dei errori. Poi usi to_string (definito in C++0x) e usi char * per ogni funzione. Non sarebbe stato meglio usare la classe string?
    Per il resto non so.
    Prova anche a vedere quà.
    http://www.codeproject.com/KB/IP/UniversalTCPSocketClass.aspx
  • Re: Winsock Client/Server- Inspiegabili errori 10053 / 10054

    Ciao,

    ti ringrazio prima di tutto per la risposta e per avermi segnalato il link, molto interessante.

    Ad ogni modo ho trovato il problema: nella funzione Write, la chiamata a send era scritta con il flag MSG_OOB. A dire il vero è un indicazione che presi da un esempio online.
    Settando il flag a 0, come del resto già era in Read, il tutto a iniziato a lavorare senza problemi!

    Visto che ci siamo, ti volevo spiegare che l'uso dei puntatori a char è una scelta adottata per compatibilità con alcune librerie di serializzazione che producono e richiedono tale formato.

    Per quanto riguarda l'inclusione dell'header... si, ovvio, non c'entra nulla! E' un errore di copia/incolla!

    Ultima nota, non capisco quale sia il problema nell'uso di to_string(), funzione offerta da Visual Studio.


    In ogni caso grazie del supporto!

    Al prossimo errore!
    Gianluca
  • Re: Winsock Client/Server- Inspiegabili errori 10053 / 10054

    non capisco quale sia il problema nell'uso di to_string(), funzione offerta da Visual Studio.
    Nessun problema, semplicemente non capivo perche usavi char * con un compilatore che ti offre il C++0x.
  • Re: Winsock Client/Server- Inspiegabili errori 10053 / 10054

    Ciao,

    non volevo essere assolutamente polemico, semplicemente non capivo...

    Le stringhe sono delimitate da dal carattere terminatore '\0', almeno per quanto ne so


    L'uso delle stringhe mi limiterebbe in questo senso: faccio un esempio
    
    //INVIO DI UN INTERO
    int number = 100;
    char * data = (char*)&number;
    if(socket.Write(data, sizeof(int)))
    ...
    ...
    
    In questo modo posso inviare dati grezzi, di qualunque tipo.

    Sbaglio qualcosa? Accetto molto volentieri suggerimenti...


    Ciao Ciao
    Gianluca
Devi accedere o registrarti per scrivere nel forum
4 risposte