/* SERVER.c: UDP Server Demo program for uPAC-5000 series A server listen and wait to handle the coming connections Details: Setup a server, wait for connections. While a connection has been established, receive data from clients. Compiler: BC++ 3.1, Turbo C++ 1.01 (3.01) MSVC 1.52 Compile mode: large Project: SERVER.c ..\..\..\Lib\uPAC5000.lib ..\..\Lib\tcp_dm32.lib Description UDP Demo of using sendto() and recvfrom() functions. The acccept() and connect() functions isn't needed here since recvfrom() establishes the connection. >> int recvfrom(int s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen); Receives a message from a connection. The recvfrom() function allows a connection to be made and a message to be read from the connection. The flag MSG_WAITALL is not supported. Parameters: s socket identifier; buf Buffer in which information will be stored. len Number of bytes to receive. flags Specifies optional behavior: MSG_OOB returns urgent data. MSG_PEEK returns information,allowing it to be read again on a subsequent call. from Specifies the remote host to which the connection should be made. fromlen Size of the from data structure. The finnal two arguments to recvfrom are similar to the final two arguments accept. Return Value: -1 Error. >=0 Number of bytes received. >> int sendto(int s, char *buf, int len, int flags, struct sockaddr *to, int tolen); Send a message. The sendto()function allows a connection to be made and a message to Be written to the connection. Parameters: s Socket identifier. buf Buffer from which information will be sent. len Number of bytes to send. flags Specifies optional behavior: MSG_OOB sends the data as urgent data. MSG_DONTROUTE ensures that the message is not sent through a default router. to Specifies the remote host to which the connection should be made. tolen Size of the to data structure. Return Value: -1 Error. >=0 Number of bytes sent. [Jan 05, 2012] by Liam */ #include #include #include "..\..\..\lib\upac5000.h" #include "..\..\lib\Tcpip32.h" #define SOCKET_NUM 32 // define the maximum number of sockets #define SERVICE_PORT 23 // define the service port for Server fd_set rfds; // set of socket file descriptors for reading typedef struct tagSocket_State { int active; // socket is active int init; struct sockaddr_in sin; // client address } Socket_State; Socket_State socket_state[SOCKET_NUM]; extern int errno; // error codes int UDP_server_initial(void) { /* Return: 0: on success -1: function "Ninit" error -2: function "Portinit" error */ int i, iRet; if((iRet=NetStart())<0) return iRet; FD_ZERO(&rfds); for(i=0; i=0 on success, returns a socket number */ int type, protocol; int err; int iSocket; type=SOCK_DGRAM; // UDP/IP protocol=0; // always 0 iSocket=err=socket(PF_INET, type, protocol); if(err<0) return -1; // addressing for master socket memset(&socket_state[iSocket].sin, 0, sizeof(socket_state[iSocket].sin)); socket_state[iSocket].sin.sin_family=AF_INET; socket_state[iSocket].sin.sin_addr.s_addr=0L; // INADDR_ANY is a 32bits zero value socket_state[iSocket].sin.sin_port=htons(SERVICE_PORT); // Port 23 err=bind(iSocket, (struct sockaddr *) &socket_state[iSocket].sin, sizeof(socket_state[iSocket].sin)); if(err<0) { closesocket(iSocket); return -2; } socket_state[iSocket].active=1; return iSocket; // err=0 for success } void UDP_server_shutdown(void) { int i; FD_ZERO(&rfds); // clear FD set for(i=0; i ACCEPT() request memset(&ssin, 0, sizeof(ssin)); iByte=recvfrom(i, buf, sizeof(buf), 0, (struct sockaddr*) &ssin, &sin_len); if(iByte<0) continue; if(iByte>0) { buf[iByte-1]=0; if(!strcmp(buf, "quit")) iQuit=1; else { sendto(i, buf, iByte, 0, (struct sockaddr*) &ssin, sin_len); } } } FD_CLR(i, &rfds); } } } //Step 4: Shutdown the UDP server UDP_server_shutdown(); Nterm(); }