PDA

View Full Version : echo server/client UDP in MVC++


Rigo007
27-09-2004, 10:27
ciao! Devo fare un echo server e un client ke comunicano tra loro usando il protocollo UDP!
Questo protocollo usa le funzioni sendto() e recvfrom()...
Io ho scritto questo codice...qualcuno riesce a sistemarmelo utilizzando tali funzioni?
Ho inserito nel codice dei commenti e degli esempi ke potrebbero essere utili (o fastidiosi), vedete vuoi!

Thank you...anticipatamente!

Nb. per compilare dovete inserire nel linker la libreria wsock32.lib

Rigo007
27-09-2004, 10:29
// UDP client using Winsock 2.0

#include <winsock2.h>
#include <stdlib.h>
//#include <string.h>
#include <stdio.h>
#include <conio.h>
//#include <iostream.h>

#include <string>
#include <iostream>

using namespace std ;



#define DEFAULT_PORT 5001

int main() {
char Buffer[128];
char *server_name = "localhost";
unsigned short port = DEFAULT_PORT;

//
char ch;
string s;
//

int err;
int retval;
int loopflag = 0;
int loopcount;
int maxloop = -1;
unsigned int addr;
struct sockaddr_in server;
struct hostent *hp;
WSADATA wsaData;
WORD wVersionRequested;

SOCKET conn_sock;

wVersionRequested = MAKEWORD(2,0); // creo la variabile che contiene la versione della wsock32.dll (winsock ver 2.0)

err = WSAStartup(wVersionRequested,&wsaData); // inizializzo la wsock32.dll

if(err != 0) {
printf(" Nessuna winsock trovata!\n");
fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
WSACleanup();
return(-1);
} else
printf(" Vers$ %d \n nHVer$ %d \n nMaxSock %d \n nMaxUdpDg %d \n Description: %s\n Status: %s\n\n",
wsaData.wVersion,
wsaData.wHighVersion,
wsaData.iMaxSockets,
wsaData.iMaxUdpDg,
wsaData.szDescription,
wsaData.szSystemStatus);

printf(" --> CLIENT UDP <--\n\n");

/*
Attempt to detect if we should call gethostbyname() or gethostbyaddr()
*/

if(isalpha(server_name[0])) { // server address is a name
hp = gethostbyname(server_name);
} else { // convert nnn.nnn address to a usable one
addr = inet_addr(server_name);
hp = gethostbyaddr((char *)&addr,4,AF_INET);
}

if(hp == NULL) {
fprintf(stderr," Client --> Cannot resolve address [%s] : Error %d\n",
server_name,WSAGetLastError());
WSACleanup();
exit(1);
}

// Copy the resolved information into the sockaddr_in structure

memset(&server,0,sizeof(server));
memcpy((&server.sin_addr),hp->h_addr,hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(port);

conn_sock = socket(AF_INET,SOCK_DGRAM,0);

if(conn_sock< 0) {
fprintf(stderr," Client --> Error opening socket : Error %d\n",WSAGetLastError());
WSACleanup();
return(-1);
}

/*
Notice that nothing in this code is specific to whether we
are using UDP or TCP.
We achieve this by using a simple trick.
When connect() is called on a datagram socket, it does not
actually establish the connection as a stream (TCP) socket
would. Instead, TCP/IP establishes the remote half of the
(LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
This enables us to use send() and recv() on datagram sockets,
instead of recvfrom() and sendto()
*/

printf(" Client connecting to: %s\n",hp->h_name);

// while(ch != 0x1b) {
// ch = getchar();
// getline(cin,s,'\n');
// err = sendto(conn_sock,&ch,sizeof(Buffer),0,(struct sockaddr *)&server,sizeof(struct sockaddr));
// }

err = sendto(conn_sock,Buffer,sizeof(Buffer),0,(struct sockaddr *)&server,sizeof(struct sockaddr));

if(err == SOCKET_ERROR) {
fprintf(stderr," sendto() failed: %d\n",WSAGetLastError());
WSACleanup();
return(-1);
}


// --------------------------------------------------------------------------------

/*

ESEMPIO SOTTO LINUX

if((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
perror("sendto");
exit(1);
}
printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(their_addr.sin_addr));

/*
FUNZIONE SENDTO()

int sendto(SOCKET s,const char FAR * buf,int len,int flags,const struct sockaddr FAR * to,int tolen);

Parameters:
s
[in] A descriptor identifying a (possibly connected) socket.
buf
[in] A buffer containing the data to be transmitted.
len
[in] The length of the data in buf.
flags
[in] An indicator specifying the way in which the call is made.
to
[in] An optional pointer to the address of the target socket.
tolen
[in] The size of the address in to.

*/
/*
ESEMPIO con FTP protocol

char mess[100]; // il messaggio inviato dal Server (max 100 byte);
int n = 0;

n = recv(miosock,mess,100,0); // si riceve il messaggio di benvenuto dal Server

mess[n] = 0; // n rappresenta la lunghezza del messaggio in arrivo (max 100 byte)
printf(mess); // lo visualizzo

while(ch != 0x1b) { // finchč ch č diverso da ESC
ch = getchar(); // aspetto un carattere
send(miosock,&ch,1,0); // e lo invio al Server
}


/*

while(ch!=0x1b) { // finchč ch č diverso dal tasto ESC
ch = getchar(); // aspetto un carattere
send(miosock,&ch,1,0); // e lo invio al Server
}


// */

// ----------------------------------------------------------------------------------------------------------

/*
if(connect(conn_sock,(struct sockaddr*)&server,sizeof(server)) == SOCKET_ERROR) {
fprintf(stderr," connect() failed: %d\n",WSAGetLastError());
WSACleanup();
return(-1);
}
*/

// cook up a string to send

loopcount = 0;

while(1) {

wsprintf(Buffer," This is a small message [number %d]",loopcount++);
retval = send(conn_sock,Buffer,sizeof(Buffer),0);

if(retval == SOCKET_ERROR) {
fprintf(stderr," send() failed: error %d\n",WSAGetLastError());
WSACleanup();
return -1;
}

printf(" Sent Data [%s]\n",Buffer);

retval = recv(conn_sock,Buffer,sizeof(Buffer),0);

if (retval == SOCKET_ERROR) {
fprintf(stderr," recv() failed: error %d\n",WSAGetLastError());
closesocket(conn_sock);
WSACleanup();
return -1;
}

/*
We are not likely to see this with UDP, since there is no
'connection' established.
*/

if (retval == 0) {
printf(" Server closed connection\n");
closesocket(conn_sock);
WSACleanup();
return -1;
}

printf(" Received %d bytes, data [%s] from server\n",retval,Buffer);

if(!loopflag) {
printf(" Terminating connection\n");
break;
}
else {
if ( (loopcount >= maxloop) && (maxloop >0) )
break;
}
}

closesocket(conn_sock);
WSACleanup();
getch();

return(0);

}

Rigo007
27-09-2004, 10:30
/*
Simple UDP server using Winsock 2.0
*/

#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define DEFAULT_PORT 5001

int main() {

char Buffer[128];
unsigned short port = DEFAULT_PORT;
int retval;
int fromlen;
int err;
struct sockaddr_in local,from;
WSADATA wsaData; // variabile che contiene i parametri di WSAStartup()
WORD wVersionRequested;

wVersionRequested = MAKEWORD(2,0); // creo la variabile che contiene la versione della wsock32.dll (winsock ver 2.0)

err = WSAStartup(wVersionRequested,&wsaData); // inizializzo la wsock32.dll

printf(" --> SERVER UDP <--\n\n");

if(err != 0) {
printf(" Nessuna winsock trovata!\n");
exit(1);
} else
printf(" Vers$ %d \n nHVer$ %d \n nMaxSock %d \n nMaxUdpDg %d \n Description: %s\n Status: %s\n\n",
wsaData.wVersion,
wsaData.wHighVersion,
wsaData.iMaxSockets,
wsaData.iMaxUdpDg,
wsaData.szDescription,
wsaData.szSystemStatus);

/*
Il codice soprastante serve per inizializzare la wsock32.dll, tramite la funzione WSAStartup()
che č specifica di Windows; le vengono passate come argomenti la versione di libreria richiesta
e l'indirizzo ad una struttura WSAData, che verrā riempita dalla WSAStartup con informazioni
relative alla libreria stessa.
In caso di errore la WSAStartup ritorna un codice diverso da 0 che stā ad indicare l'errore in questione
(fai riferimento al file winsock.h per la lista dei #define).
Il prefisso WSA stā ad indicare Windows Socket API.
*/

SOCKET listen_socket ,msgsock;

local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;

// Port must be in Network Byte Order

local.sin_port = htons(port);

listen_socket = socket(AF_INET,SOCK_DGRAM,0);

if(listen_socket == INVALID_SOCKET) {
fprintf(stderr," socket() failed with error %d\n",WSAGetLastError()); // scrivo su file
WSACleanup();
return(-1);
}

/*
bind() associates a local address and port combination with the
socket just created. This is most useful when the application is a
server that has a well-known port that clients know about in advance.
*/

err = bind(listen_socket,(struct sockaddr*)&local,sizeof(local));

if(err == SOCKET_ERROR) {
fprintf(stderr," bind() failed with error %d\n",WSAGetLastError());
WSACleanup();
return(-1);
}

printf(" --> 'Listening' on port %d, protocol UDP\n",port);

while(1) {

fromlen = sizeof(from);

msgsock = listen_socket;

/*
for SOCK_DGRAM (UDP), the server will do
recvfrom() and sendto() in a loop.
*/

retval = recvfrom(msgsock,Buffer,sizeof(Buffer),0,(struct sockaddr*)&from,&fromlen);
printf(" Received datagram from %s\n",inet_ntoa(from.sin_addr));

if(retval == SOCKET_ERROR) {
fprintf(stderr," recvfrom() failed with error %d\n",WSAGetLastError());
closesocket(msgsock);
continue;
}
if(retval == 0) {
printf( " Client closed connection\n");
closesocket(msgsock);
continue;
}

printf(" Received %d bytes, data [%s] from client\n",retval,Buffer);

printf(" Echoing same data back to client\n");

retval = sendto(msgsock,Buffer,sizeof(Buffer),0,(struct sockaddr*)&from,fromlen);

if(retval == SOCKET_ERROR) {
fprintf(stderr," sendto() failed with error %d\n",WSAGetLastError());
}

printf(" UDP server looping back for more requests\n");

continue;
}
}