home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // This program illustrates a simple tcp/udp client implementation
- //-----------------------------------------------------------------------------
-
- #ifdef WIN32
- #include <windows.h>
- #endif
-
- #include <stdio.h>
- #include <time.h>
-
- #include <rpcdc.h>
-
- //-----------------------------------------------------------------------------
- // Here is a definition of a structure that must be transmitted to the server
- // One possibility is to develop a specific XDR function, used with transmit/
- // receive functions
- //-----------------------------------------------------------------------------
- typedef struct _TEST {
-
- int i1;
- int i2;
- int i3;
-
- float f;
- double d;
-
- } TEST;
-
- //-----------------------------------------------------------------------------
- // First write the XDR function - standard structure
- // The parameters are as follows :
- // h : (void *) points to the host binary representation of the data
- // n : (void *) points to the network binary representation of the data
- // code : indicates the operation to perform (3 possibilities)
- // --> XDR_ENCODE : conversion h -> n
- // --> XDR_DECODE : conversion n -> h
- // --> XDR_MEMORY : just returns the size of the object
- //-----------------------------------------------------------------------------
- size_t _xdr_TEST (void *h, void *n, int code)
-
- {
- TEST *hi=(TEST *)h; // first convert pointers
- char *ni=(char *)n;
- size_t size;
-
- switch (code) {
-
- case XDR_ENCODE:
- case XDR_DECODE:
-
- size=_xdr_int(NULL,NULL,XDR_MEMORY);
- _xdr_int((void *)&hi->i1,(void *)ni,code); ni+=size;
- _xdr_int((void *)&hi->i2,(void *)ni,code); ni+=size;
- _xdr_int((void *)&hi->i3,(void *)ni,code); ni+=size;
-
- size=_xdr_float(NULL,NULL,XDR_MEMORY);
- _xdr_float((void *)&hi->f,(void *)ni,code); ni+=size;
-
- size=_xdr_double(NULL,NULL,XDR_MEMORY);
- _xdr_double((void *)&hi->d,(void *)ni,code); ni+=size;
- return 0;
-
- case XDR_MEMORY:
- default:
- return 3*_xdr_int(NULL,NULL,XDR_MEMORY)+
- _xdr_float(NULL,NULL,XDR_MEMORY)+
- _xdr_double(NULL,NULL,XDR_MEMORY);
- }
- }
-
- //-----------------------------------------------------------------------------
- // Now the function to send a TEST structure becomes very simple !
- // The following example returns 1 if success, 0 if a problem occurs.
- // Binary conversion is automatically performed through the XDR routine
- // written above.
- // Warning : remember to call _rpc_flush() !
- //-----------------------------------------------------------------------------
- int _rpcsend_TEST (SOCKET Socket,
- RPC_MSG *rpc_msg, XDR_BUFFER *xdr_buffer,
- TEST *TestParameter)
-
- {
- return _rpcsend_buffer(Socket,rpc_msg,xdr_buffer,TestParameter,_xdr_TEST)==
- _xdr_TEST(NULL,NULL,XDR_MEMORY);
- }
-
- //-----------------------------------------------------------------------------
- // Similarly, the function to receive a TEST structure is also simple.
- // Binary conversion is automatically performed through the XDR routine
- // written above.
- //-----------------------------------------------------------------------------
- int _rpcrecv_TEST (SOCKET Socket,
- XDR_BUFFER *xdr_buffer,
- TEST *TestParameter)
-
- {
- return _rpcrecv_buffer(Socket,xdr_buffer,TestParameter,_xdr_TEST)==
- _xdr_TEST(NULL,NULL,XDR_MEMORY);
- }
-
- //-----------------------------------------------------------------------------
- // tcp client implementation
- //-----------------------------------------------------------------------------
- void mainTCP (char *server, char *service)
-
- {
- SOCKET Socket; // to communicate with the server
- RPC_MSG rpc_msg; // for transmission buffering
- XDR_BUFFER xdr_buffer; // for XDR buffering
- char msg[256];
- int ans;
- time_t t;
- TEST Test;
-
- time(&t);
-
- // Initialization of the TEST structure
- Test.i1=10;
- Test.i2=17;
- Test.i3=25;
- Test.f=3.14159f;
- Test.d=2.7182818;
-
- // Connection request to the specified server, with the specified service
- Socket=_StartTCPClient(server,
- service,
- 10,
- &rpc_msg,
- &xdr_buffer);
-
- // An error occured, or the connection has been rejected
- if (Socket==0) {
- _GetErrMsg(msg);
- printf("%s\n",msg);
- return;
- }
-
- // Now the connection has been accepted !
-
- // The first int (value 1) corresponds to the first rpc message transmitted to the server
- _rpcsend_int(Socket,&rpc_msg,&xdr_buffer,1);
- // This message also uses an additionnal parameter (int) : here the local time
- _rpcsend_int(Socket,&rpc_msg,&xdr_buffer,(int)t);
- // The last part of the message is made of the TEST structure defined above
- _rpcsend_TEST(Socket,&rpc_msg,&xdr_buffer,&Test);
- // flushing is required !
- _rpc_flush(Socket,&rpc_msg);
-
- // Now I am waiting for the answer coming from the server !
- // In this example, the first int is modified and returned, same for the TEST structure.
- _rpcrecv_int(Socket,&xdr_buffer,&ans);
- _rpcrecv_TEST(Socket,&xdr_buffer,&Test);
- printf("Message sent to server : %d\n",t);
- printf("Server answered : %d\n",ans);
- printf("New TEST : %d %d %d %g %lg\n",Test.i1,Test.i2,Test.i3,Test.f,Test.d);
-
- // OK ! seems to work, bye !
- _StopTCPClient(Socket,&rpc_msg,&xdr_buffer);
- }
-
- //-----------------------------------------------------------------------------
- // udp client implementation
- //-----------------------------------------------------------------------------
- void mainUDP (char *service)
-
- {
- SOCKET udpSocket;
- sockaddr_in bcast_addr,src_addr;
- long int udpQuery;
- int end,stat,len;
- struct hostent *host;
- time_t t1,t2;
- struct timeval timeout={0,0};
- char sz_info[256];
- struct {
- long int udpResponse;
- char szb[128];
- } udp;
-
- // Creation of the socket corresponding to the specified service
- udpSocket=_StartUDPClient(service,10,&bcast_addr);
- if (udpSocket==0) {
- _GetErrMsg(sz_info);
- printf("%s\n",sz_info);
- return;
- }
-
- // The udp message is 32 bits long, the value is just 1 in this example
- udpQuery=htonl(1);
- stat=sendto(udpSocket,(char *)&udpQuery,sizeof(long int),0,
- (const struct sockaddr *)&bcast_addr,sizeof(sockaddr_in));
- if (stat!=sizeof(long int)) {
- _StopUDPClient(udpSocket);
- return;
- }
-
- // Now I am waiting for answers coming from the different servers, max. delay 10 seconds
- time(&t1);
- end=0;
- do {
- switch (_socket_ready_r(udpSocket,&timeout)) {
- case -1: // this is an error !
- end=1;
- break;
- case 0: // no error, socket not ready !
- time(&t2);
- end=(t2-t1)>10;
- break;
- default: // no error, socket ready !
- len=sizeof(src_addr);
- stat=recvfrom(udpSocket,(char *)&udp,sizeof(udp),0,
- (struct sockaddr *)&src_addr,&len);
- if (stat==sizeof(udp)) {
- udp.udpResponse=ntohl(udp.udpResponse);
- switch (udp.udpResponse) {
- case 2: // the server answers 2 (1+udpQuery) : good !
- strcpy(sz_info,udp.szb);
- break;
- default:
- strcpy(sz_info,"");
- }
- if (strlen(sz_info)!=0) {
- host=gethostbyaddr((char *)&src_addr.sin_addr,sizeof(struct in_addr),PF_INET);
- if (host!=NULL) printf("%s : ",host->h_name);
- else printf("%s : ",inet_ntoa(src_addr.sin_addr));
- printf("%s\n",sz_info);
- }
- }
- }
- } while (!end);
-
- _StopUDPClient(udpSocket);
- }
-
- //-----------------------------------------------------------------------------
- // main function
- //-----------------------------------------------------------------------------
- int main (int argc, char **argv)
-
- {
-
- if (argc!=3) {
- printf("usage : %s <server> <service> for tcp test\n",argv[0]);
- printf("usage : %s - <service> for udp test\n",argv[0]);
- return 0;
- }
-
- if (strcmp(argv[1],"-")==0) mainUDP(argv[2]);
- else mainTCP(argv[1],argv[2]);
-
- return 0;
- }
-