// udp-chat is a proram that read from the STDIN and send to a remote server // to Compile: use the Makefile /* include files */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_LEN 128 #define FALSE 0 #define TRUE 1 /* functions declarations */ void chat(int udpSock); void sendMessage(int outSock, int *FLAG); void getMessage(int inSock); char remoteServer[32]; int remotePort; main(int argc,char *argv[]) { int InSock, OutSock; /* parse the command line to get the info of local and remote client/server */ if (argc != 4) { printf("Usage: udp-chat LocalPort RemoteHostName RemotePort\n"); exit(1); } else memset(remoteServer,0,sizeof(remoteServer)); strcpy(remoteServer, argv[2]); remotePort = atoi(argv[3]); printf("RemoteServer (%s) and Port (%d) \n", remoteServer, remotePort); InSock = passiveUDP(argv[1]); printf("creating Passive UDP sock for receiving ..\n"); //OutSock = connectUDP(argv[2],argv[3]); printf("Creating connected UDP socket for Sending -- bin to a port\n"); chat(InSock); close(InSock); // close(OutSock); } /* This functions takes care of the actual sending and recieving of messages. It reads text from the STDIN and sends the message to the locasl host and port, and it reads messages sent by the binded port from the socket and displays them to the STDOUT */ void chat(int udpSock) { fd_set rfds,rfds_copy; struct timeval wait; int DONE=FALSE; int len; int nb=0; /* set the bits corresponding to STDIN and the socket to be monitored */ FD_ZERO(&rfds); FD_ZERO(&rfds_copy); FD_SET(0,&rfds); // adding STDIN to select bag FD_SET(udpSock,&rfds); // adding the receiving socket to select bag len = udpSock +1; /* set the monitoring frequency to 1 second */ wait.tv_sec = 0; wait.tv_usec = 5000; printf("type in message to be sent to the Remote UDP chat followed by ENTER\n"); printf("hit CTRL-D to quit from the group \n"); /* monitor the socket and STDIN to get/send messages from/to the group */ while(!DONE) { memcpy(&rfds_copy, &rfds, sizeof(rfds_copy)); nb = select(len, &rfds_copy, (fd_set *)0, (fd_set *)0,(struct timeval *)0); // for select blocking mode // for select mode with timer //nb = select(len,&rfds_copy,(fd_set *) 0,(fd_set *) 0,&wait); if (nb<0) { printf("error in select \n"); exit(-1); } else if (nb > 0) { if(FD_ISSET(0,&rfds_copy)) // is there any input in the STDIN?, if so then read and sent it {printf("Sending .... \n"); //sendMessage(OutSock,&DONE); } sendMessage(udpSock,&DONE); } if(FD_ISSET(udpSock,&rfds_copy)) // is there any input in the receiving socket? if so read and print it. {printf("Receiving ....\n"); getMessage(udpSock);} } } } /* This function reads the input from STDIN and sends it to the group */ void sendMessage(int outSock,int *flag) { char sendBuf[MAX_LEN]; struct hostent *phe; /* pointer to host information entry */ int bytes=0; struct sockaddr_in dest; bytes = read(0, sendBuf,MAX_LEN); // reading from the STDIN if (bytes < 0) { printf("error in reading from STDIN \n"); exit(-1); } else if(bytes == 0) *flag = TRUE; else { sendBuf[bytes] = '\0'; //printf("Outsock=%d, msg=%s, bytes=%d\n", outSock,sendBuf,bytes); memset(&dest, 0, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(remotePort); //dest.sin_addr.s_addr = INADDR_ANY; /* Map host name to IP address, allowing for dotted decimal */ if ( phe = gethostbyname(remoteServer) ) memcpy(&dest.sin_addr, phe->h_addr, phe->h_length); else if ((dest.sin_addr.s_addr = inet_addr(remoteServer)) == INADDR_NONE ) errexit("can't get \"%s\" host entry\n", remoteServer); //inet_pton(AF_INET, remoteServer, &dest.sin_addr); sendto(outSock, (const char *)sendBuf, bytes, MSG_CONFIRM, (const struct sockaddr *) &dest, sizeof(dest)); /* if ( write(outSock,sendBuf,bytes) < 0 ) // you can use sendto() instead { printf("error in sendto %s\n", strerror(errno)); exit(-1); } */ } } /* Get the UDP message sent by the group and print out to STDOUT */ void getMessage(int inSock) { int bytes=0; char recvBuf[MAX_LEN]; //bytes = recv(inSock,recvBuf,MAX_LEN,0); printf("Reading ....\n"); bytes = read(inSock,recvBuf,MAX_LEN); // reading msgs from the receiving socket if (bytes < 0) { printf("error in reading from UDP socket\n"); exit(-1); } else if(bytes == 0) printf("zero bytes read\n"); else /* print the message to STDOUT */ { if (write(1,recvBuf,bytes) < 0) // print it to the STDOUT { printf("error in write to STDOUT \n"); exit(-1); } } }