Problema con socket

di il
11 risposte

Problema con socket

Salve,
stavo cercando di creare un server multiclient per studio ma sono incappato in un problema
Quando connetto anche un solo client al server,questo comincia a stampare "byte recv -1" all'infinito.
Incollo il source in c++/cli
void main()
{
	printf("############################## SERVER #####################################\n\n");
	temp = WSAStartup(MAKEWORD(2,2),&data);
	if(temp != NO_ERROR)
	{
		printf("Error in WSAStartup");
		system("PAUSE");
	}
	
	ZeroMemory(&hints,sizeof(hints));
	hints.ai_family= AF_INET;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_socktype = SOCK_STREAM;
	sockAdd = &hints;

	ZeroMemory(&collection_sock,sizeof(collection_sock));
	for (int i = 0; i < 30; i++)
	{
	collection_sock[i] = 0;
	}


	temp = getaddrinfo(NULL,DEFAULT_PORT,&hints,&sockAdd);
	if (temp < 0 )
	{
		printf("Getaddrinfo error");
		system("PAUSE");
	}

	master_sock = socket(sockAdd->ai_family,sockAdd->ai_socktype,sockAdd->ai_protocol);
	if (master_sock == INVALID_SOCKET)
	{
		printf("Error in creating socket");
		system("PAUSE");
	}

	if (setsockopt (master_sock,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val)) == SOCKET_ERROR)
	{
		printf("error with setsockopt func");
		system("PAUSE");
	 }

	temp = bind(master_sock,sockAdd->ai_addr,sockAdd->ai_addrlen);
	if (temp == SOCKET_ERROR)
	{
		printf("Error in bind %d\n",WSAGetLastError());
		system("PAUSE");
	}
	
	temp = listen(master_sock,3);
	if (temp < 0)
	{
		printf("Error with listen func");
		system("PAUSE");
	}

	SOCKET client;
	int activity = NULL;
	
	while (true)
	{

		FD_ZERO(&fds);
	    FD_SET(master_sock,&fds);

		for(int i = 0; i < 30; i++)
		{
		if(collection_sock[i] > 0)
		FD_SET(collection_sock[i],&fds);
		}

		activity = select(master_sock + 1,&fds,NULL,NULL,0);
		    
		
		if (FD_ISSET(master_sock,&fds))
		{
		    
			client = accept(master_sock,(sockaddr *)&addInfo,(int *)sizeof(addInfo));
			FD_SET(client,&fds);
			   do
			   {
			   sendResult = recv(client,recvBuffer,sizeof(recvBuffer),NULL);
			   printf("byte recv %d\n",sendResult);
			   }while(sendResult > 0);

	        for(int i = 0; i < 30; i++)
			{
			if(collection_sock[i] = 0)
				collection_sock[i] = client;
			break;
			}
		
		
		
		
		}
		



	}
	
}
	
Credo di aver fatto un casino con le varie macro di select()....
Ho già chiesto ad altre persone ma nessuno mi ha saputo o avuto tempo di darmi una risposta esaustiva...
Grazie in anticipo a tutti quanti risponderanno.

11 Risposte

  • Re: Problema con socket

    -1 indica che è avvenuto un errore, controlla quale errore.

    Dato che usi Windows devi utilizzare la API WSAGetLastError dopo la recv
  • Re: Problema con socket

    Il bello è proprio che non c'è nessun errore,la chiamata a WSAGetLastError non dice niente...
  • Re: Problema con socket

    La WSAGetLastError restituisce un valore ... quale ... e dove l'hai inserita?
  • Re: Problema con socket

    Avevo sbagliato io che non avevo messo il "%d".
    Comunque,il numero è dell''errore è 10038 "Socket operation on nonsocket."
  • Re: Problema con socket

    Quell'errore indica che, nella recv, non hai usato un socket valido.

    Dato che il codice è molto "incasinato" e non è compilabile per provarlo (mancano tutte le dichiarazioni delle variabili), non posso dirti molto altro.
  • Re: Problema con socket

    Chiedo venia per il codice incasinato ma ci sto perdendo la testa con questo problema...
    Le dichiarazioni sono queste:
    #ifdef UNICODE
    #undef UNICODE
    #endif
    #ifdef _UNICODE
    #undef _UNICODE
    #endif
    #ifndef WIN32_LEAN_AND_MEAN
    #define WIN32_LEAN_AND_MEAN
    #endif
    #define DEFAULT_PORT "27015"
    #define DEFAULT_BUFLEN 512
    #define MAX_SOCK 3
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <WinSock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #pragma comment (lib,"Ws2_32.lib")
    
    sockaddr_in addInfo;
    WSAData data;
    addrinfo hints,
    	*sockAdd;
    int temp,count,sendResult;
    char recvBuffer[DEFAULT_BUFLEN];
    fd_set fds;
    SOCKET master_sock;
    char val = TRUE;
    SOCKET collection_sock[30];
    int max_clients,sd,max_sd;
    int iResult,iSendResult;
    
  • Re: Problema con socket

    Dato che l'errore indica che nella riga

    sendResult = recv(client,recvBuffer,sizeof(recvBuffer),NULL);

    NON stai operando con un socket, allora vuol dire che

    client

    non ha un valore corretto (infatti, da debug, appare uguale a -1).

    Dato che "client" viene assegnato da

    client = accept(master_sock,(sockaddr *)&addInfo,(int *)sizeof(addInfo));

    è la accept che fallisce e semplicemente perché è usata male.
    L'ultimo parametro è un "puntatore ad un int" e non puoi pensare di fare il cast in quel modo perché non ha senso. Dovrai prevedere una variabile intera, a cui assegnare il valore della sizeof e passare il puntatore alla variabile in modo che la accept ci possa scrivere (al contrario, tenterebbe di scrivere in un indirizzo inesistente). Quindi dovrà essere

    int alen = sizeof(addInfo);
    client = accept(master_sock,(sockaddr *)&addInfo, &alen);
  • Re: Problema con socket

    Ho aggiustato i parametri di accept() e ora il server mi riceve tutto ciò che mando...anche se il server riceve i dati solo da un client alla volta...devo prima chiuderne uno affinche un altro possa inviare...
  • Re: Problema con socket

    Dovrai usare più thread, uno per client.
  • Re: Problema con socket

    Grazie innanzitutto per i commenti che mi hai aiutato un casino...
    Ultima domanda: Ma quindi select() non è un sostituto del metodo multi-thread?
  • Re: Problema con socket

    Sì ma è tremendamente più "contorto" ... con i thread è molto più semplice.

    In ogni caso, dopo la accept, devi dialogare con tutti i client attualmente connessi ... vedi un po' la risposta in questo thread

    http://stackoverflow.com/questions/16328118/simple-tcp-server-with-multiple-clients-c-unix
Devi accedere o registrarti per scrivere nel forum
11 risposte