220 likes | 342 Views
Part 2. Socket Programming. UDP. Socket programming with UDP. UDP : no “connection” between client and server no handshaking sender explicitly attaches IP address and port of destination to each packet server must extract IP address, port of sender from received packet
E N D
Part 2 Socket Programming UDP
Socket programming with UDP UDP: no “connection” between client and server no handshaking sender explicitly attaches IP address and port of destination to each packet server must extract IP address, port of sender from received packet UDP: transmitted data may be received out of order, or lost application viewpoint: UDP provides unreliable transfer of groups of bytes (“datagrams”) between client and server Application 2-2
Client/Server Socket Interaction: UDP • No handshaking. • No streams are attached to the sockets. • Sender creates packets of bytes with destination IP address and Port number. • Receiving host must unravel each packet received to obtain the packet’s information bytes.
Client/server socket interaction: UDP Client create socket, Create datagram with server (hostid, port=x), send datagram viaclientSocket read datagram from serverSocket write reply to serverSocket specifying client address, port number read datagram from clientSocket close clientSocket Server (running on hostid) create socket, port= x. clientSocket= socket(PF_INET, SOCK_DGRAM,0) serverSocket = socket(PF_INET, SOCK_DGRAM,0) Application 2-4
Example: UDP client Client process Input: receives packet (recall that TCP receives a “byte stream”) Output: sends packet (recall that TCP sends a “byte stream”) client UDP socket Application 2-5
Functions and Data Structures
sendto() • Send data through a socket: sendto(SOCKET s, char *msg, int msglen, int flags, structsockaddr *to, int *tolen); PARAMETERS s = socket (inside the socket descriptor: port and IP address...) msg = a pointer to a buffer (could be a string) msglen = the length of the buffer flags = 0 (forget about them for this exercise...) to=structure of address with the IP / port # tolen=length of the structure Example: sendto(s, sbuffer, strlen(sbuffer),0,(structsockaddr*) to, &len);
recvfrom() • Receive data int recvfrom(SOCKET s, char *msg, int msglen, int flags, structsockaddr *from, int *fromlen) PARAMETERS s = socket (inside the socket descriptor: port and IP address...) msg = a pointer to a buffer msglen = the length of the buffer flags = 0 from =structure of address with the IP / port # fromlen=length of the structure Example: recvfrom(s, rbuffer, 1, 0,(structsockaddr *) &from, &len);
Test the UDP Client-Server Codes • Run the server: ServerUDP1235 • Compile ClientUDP.c, look for the executable. • Run ClientUDP.exe from the command prompt to connect to the server: • ClientUDPlocalhost 1235 • orClientUDP127.0.0.11235 • Alternatively, use IpConfig to find out what your IP address is: (e.g. 130.123.123.111), then connect to the server using: • ClientUDP130.123.123.1111235
Client UDP #include <stdio.h> #include <string.h> #include <stdlib.h> #include <winsock2.h> #define WSVERS MAKEWORD(2,0) WSADATA wsadata; #define BUFFERSIZE 80 #define SEGMENTSIZE 78 void get_keyboard(char * send_buffer) { fgets(send_buffer,SEGMENTSIZE,stdin); if (send_buffer[strlen(send_buffer)-1]=='\n') { //if the last one is \n, which means there is at least one ‘\0’ after it send_buffer[strlen(send_buffer)-1]='\r'; send_buffer[strlen(send_buffer)]='\n'; } else { send_buffer[strlen(send_buffer)]='\n'; //write \n on the last byte } } clientUDP.cpp //In LINUX #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h>
Client UDP int main(int argc, char *argv[]) { //******************************************************************* // Initialization //******************************************************************* structsockaddr_inlocaladdr,remoteaddr; memset(&localaddr, 0, sizeof(localaddr));//clean up memset(&remoteaddr, 0, sizeof(remoteaddr));//clean up //******************************************************************** // WSSTARTUP //******************************************************************** if (WSAStartup(WSVERS, &wsadata) != 0) { WSACleanup(); printf("WSAStartup failed\n"); } int s; char send_buffer[BUFFERSIZE],receive_buffer[BUFFERSIZE]; int n,bytes; if (argc == 1) { printf("USAGE: client IP-address [port]\n"); exit(1); } //Port number: get it from argv[2], convert/copy to sin_port if (argc == 3) remoteaddr.sin_port = htons((u_short)atoi(argv[2])); else remoteaddr.sin_port = htons(1234); //Family of protocols remoteaddr.sin_family = AF_INET; clientUDP.cpp
Client UDP //******************************************************************* //GETHOSTBYNAME //******************************************************************* structhostent *h; if ((h=gethostbyname(argv[1])) != NULL) { memcpy(&remoteaddr.sin_addr,h->h_addr,h->h_length); //get remote IP address } else if ((remoteaddr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE) { printf("An error occured when trying to translate to IP address\n"); exit(1); } //******************************************************************* //CREATE CLIENT'S SOCKET //******************************************************************* s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { printf("socket failed\n"); exit(1); } printf("\nSOCKET created.\n"); memset(send_buffer, 0, sizeof(send_buffer));//clean up printf("\nwaiting for user input...\n"); clientUDP.cpp
Client UDP get_keyboard(send_buffer); while (strncmp(send_buffer,".",1) != 0) { //******************************************************************* //SEND //******************************************************************* bytes = sendto(s, send_buffer, strlen(send_buffer),0, (structsockaddr *)(&remoteaddr),sizeof(remoteaddr) ); printf(“TO SENDER: %s \n",send_buffer); if (bytes < 0) { printf("send failed\n"); exit(1); } memset(send_buffer, 0, sizeof(send_buffer));//clean up get_keyboard(send_buffer); } closesocket(s); //close(s); //in Linux return 0; } clientUDP.cpp
Server UDP #include <errno.h> #include <stdio.h> #include <string.h> #include <winsock2.h> #define WSVERS MAKEWORD(2,0) WSADATA wsadata; #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif int main(int argc, char *argv[]) { //******************************************************************** // INITIALIZATION //******************************************************************** structsockaddr_inlocaladdr,remoteaddr; int s; char send_buffer[80],receive_buffer[80]; char remoteIP[INET_ADDRSTRLEN]; int remotePort=1234; int localPort;//no need for local IP... int n,bytes,addrlen; memset(&localaddr,0,sizeof(localaddr));//clean up the structure memset(&remoteaddr,0,sizeof(remoteaddr));//clean up the structure serverUDP.cpp
Server UDP //******************************************************************** // WSSTARTUP //******************************************************************** if (WSAStartup(WSVERS, &wsadata) != 0) { WSACleanup(); printf("WSAStartup failed\n"); } //******************************************************************** //SOCKET //******************************************************************** s = socket(PF_INET, SOCK_DGRAM, 0); if (s <0) { printf("socket failed\n"); } localaddr.sin_family = AF_INET; if (argc == 2) localaddr.sin_port = htons((u_short)atoi(argv[1])); else localaddr.sin_port = htons(1235);//default port localaddr.sin_addr.s_addr = INADDR_ANY;//server address should be local //******************************************************************** //BIND (notice, no listen()...)? //******************************************************************** if (bind(s,(structsockaddr *)(&localaddr),sizeof(localaddr)) != 0) { printf("Bind failed!\n"); return 1; } serverUDP.cpp
Server UDP //INFINITE LOOP //******************************************************************** while (1) { addrlen = sizeof(structsockaddr_in); //******************************************************************** //RECEIVE printf("Waiting... \n"); bytes = recvfrom(s, receive_buffer, 78, 0,(structsockaddr *)(&remoteaddr),&addrlen); printf("Received %d bytes\n",bytes); //******************************************************************** //PROCESS REQUEST //******************************************************************** n=0; while (n<bytes){ n++; if ((bytes < 0) || (bytes == 0)) break; if (receive_buffer[n] == '\n') { /*end on a LF*/ receive_buffer[n] = '\0'; break; } if (receive_buffer[n] == '\r') /*ignore CRs*/ receive_buffer[n] = '\0'; } if ((bytes < 0) || (bytes == 0)) break; printf("After processing, recvbuffer is %s \n",receive_buffer); } closesocket(s); return 0; } serverUDP.cpp
fgets function <cstdio> char * fgets ( char * str, int num, FILE * stream ); Get string from stream Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first. A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str. A null character is automatically appended in str after the characters read to signal the end of the C string. Parameters str Pointer to an array of chars where the string read is stored. num Maximum number of characters to be read (including the final null-character). Usually, the length of the array passed as str is used. stream Pointer to a FILE object that identifies the stream where characters are read from. To read from the standard input, stdin can be used for this parameter. www.cplusplus.com
memset function <cstring> void * memset ( void * ptr, int value, size_t num ); Fill block of memory Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char). Parameters ptr Pointer to the block of memory to fill. value Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value. num Number of bytes to be set to the value. www.cplusplus.com