Newsgroup: it.comp.programmare.win32
Titolo: perche' diavolo questo codice non funge?

traggo da "network programmig for microsoft windows"
// Module Name: tcpserver.cpp
//
// Description:
//
// This sample illustrates how to develop a simple TCP server application
// that listens for a TCP connection on port 5150 and receives data. This
// sample is implemented as a console-style application and simply prints
// status messages when a connection is accepted and when data is received
// by the server.
//
// Compile:
//
// cl -o tcpserver tcpserver.cpp ws2_32.lib
//
// Command Line Options:
//
// tcpserver.exe
//
// NOTE: There are no command parameters.
//
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int ClientAddrLen=0;
int Port = 5150;
int Ret;
char DataBuffer[1024];
// Initialize Winsock version 2.2
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
// NOTE: Since Winsock failed to load we cannot use WSAGetLastError
// to determine the error code as is normally done when a Winsock
// API fails. We have to report the return status of the function.
printf("WSAStartup failed with error %d\n", Ret);
return;
}
// Create a new socket to listening for client connections.
if ((ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
== INVALID_SOCKET)
{
printf("socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return;
}
// Setup a SOCKADDR_IN structure that will tell bind that we
// want to listen for connections on all interfaces using port
// 5150. Notice how we convert the Port variable from host byte
// order to network byte order.
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// Associate the address information with the socket using bind.
if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr))
== SOCKET_ERROR)
{
printf("bind failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
// Listen for client connections. We used a backlog of 5 which is
// normal for many applications.
if (listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("listen failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
printf("We are awaiting a connection on port %d.\n", Port);
// Accept a new connection when one arrives.
if ((NewConnection = accept(ListeningSocket, (SOCKADDR *) &ClientAddr,
&ClientAddrLen)) == INVALID_SOCKET)
// if ((NewConnection = accept(ListeningSocket, NULL, NULL)) ==
INVALID_SOCKET)
{
printf("accept failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
// printf("We successfully got a connection from %s:%d.\n",
// inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));
printf("We successfully got a connection from \n");
// At this point you can do two things with these sockets. Await
// for more connections by calling accept again on ListeningSocket
// and start sending or receiving data on NewConnection. For
// simplicity We will stop listening for more connections by closing
// ListeningSocket. We will start sending and receiving data on
// NewConnection.
closesocket(ListeningSocket);
// Start sending and receiving data on NewConnection. For simplicity,
// we will just receive some data and report how many bytes were
// received.
printf("We are waiting to receive data...\n");
if ((Ret = recv(NewConnection, DataBuffer, sizeof(DataBuffer), 0))
== SOCKET_ERROR)
{
printf("recv failed with error %d\n", WSAGetLastError());
closesocket(NewConnection);
WSACleanup();
return;
}
printf("We successfully received %d byte(s).\n", Ret);
// For this application we do not plan to do anything else with the
// connection so we will just close the connection.
printf("We are now going to close the client connection.\n");
closesocket(NewConnection);
// When your application is finished handling the connections
// call WSACleanup.
WSACleanup();
}
(per compilarlo ovviamente include ws2_32.lib)
ora, nella riga che fa l'accept mi ritorna con un errore 10014 che, da msdn,
mi risulta essere:
WSAEFAULT (10014)
Bad address.
The system detected an invalid pointer address in attempting to use a
pointer argument of a call. This error occurs if an application passes an
invalid pointer value, or if the length of the buffer is too small. For
instance, if the length of an argument, which is a SOCKADDR structure, is
smaller than the sizeof(SOCKADDR).
se invece uso la riga subito sotto (quella commentata, dove passo i null)
tutto funge perfettamente)
qualcuno mi dice cosa c'e' di sbagliato?

> int ClientAddrLen=0;
anche lascianto int ClientAddrLen senza inizializzazione... uguale (e
infatti non c'entrava niente, ma ho tentato lo stesso)

 buffer. Se non sei interessato, la dimensione non č importante,
ovviamente.
certo che per essere un libro mspress.... vabbe'... anche loro sbagliano, ma
magari provare il codice prima di masterizzarlo :-)

 magari provare il codice prima di masterizzarlo :-)
E' incredibile a dirsi, ma chi scrive la documentazione della libreria
Winsock non ha le idee ben chiare, o assume psicofarmaci.
Ti consiglio WSALookupServiceBegin/WSALookupServiceNext/WSALookupServiceEnd,
prova a recuperare - che so - il commento di una entry DNS sia sotto WinNT e
famiglia sia sotto Win95 e famiglia.
Se ci metti meno di due giorni ti pago una pizza.
Ciao,
--
zello