CS代写 UDP 1234

IPv6 ready C/C++ Language
Goal: learn how to build client/server applications that communicate using UDP sockets
Download the udp server & client codes for this lecture

Copyright By PowCoder代写 加微信 powcoder

Socket programming with UDP
UDP is a no-frills connectionless protocol
 no handshaking required (no connection establishment delay)
 No logical connection between client and server
 Simple protocol: does not keep state information at sender and receiver  No congestion control: UDP does not throttle down its sending rate
 suitable for applications that are loss-tolerant and rate sensitive  used by DNS, live streaming and online games
UDP: transmitted data may be received out of order, or lost
 offers only a best-effort transport service
 It is up to the application process to implement any required service (i.e. reliable data transfer, error-checking, etc.)
Application viewpoint:
UDP provides unreliable transfer of groups of bytes (“datagrams”) between client and server 2

Socket programming with UDP
Similar to an ordinary postal mail, a UDP packet arriving at a destination host comes with destination and source addresses.

Socket programming with UDP UDP:
 Sender: explicitly attaches destination port number and IP address to each packet. Typically, OS attaches the source address.
 Receiver: must extract IP address, port of sender from received packet
IP datagram
UDP datagram
Source Port: 1200 Destination Port: 33434
Message…
Source IP: 47.120.100.6 Destination IP: 130.123.245.1

Client/server socket application
Let’ examine the details of UDP socket programming following a simple client-server protocol.
1. Client reads a line of characters (data) from its keyboard. If input is a single-dot (.), exit; otherwise, send data to the server.
2. Theserverreceivesthedataandperformssomeoperation on it.
3. Theserversendsthemodifieddatatotheclient.
4. Theclientreceivesthemodifieddataanddisplaystheline
on its screen
5. GobacktoStep1.
Application 2-5

Simple Client/server application: UDP Use AF_INET6 for IPv6
Server (running on hostid) create socket,
connections
port= x. serverSocket =
create socket, clientSocket =
socket(AF_INET, SOCK_DGRAM,0) Loop
Create datagram with server (hostid, port=x), send datagram via
receive datagram from serverSocket
clientSocket
send reply to serverSocket
specifying client address, port number
receive datagram from clientSocket
Close serverSocket (network admin controlled)
Close clientSocket
socket(AF_INET, SOCK_DGRAM,0)
Application 2-6

Download the sample UDP server & UDP client codes from our Stream website

Test the UDP Client-Server Codes Before you compile the codes, make sure that both client and server are
using the same addressing scheme. Set both to use either IPv4 or IPv6 • hints.ai_family = AF_INET; //for IPv4
• hints.ai_family = AF_INET6; //for IPv6
 Compile the UDP server and client programs.
 Run the server: Server_UDP 1234
 Run Client_UDP.exe from the command prompt to connect to the server:
 Client_UDP localhost 1234
 or Client_UDP 127.0.0.1 1234 //IPv4 only
 Alternatively, use the ipconfig command to find out what is the server’s IP address is: (e.g. 130.123.123.111), then connect to the server using:
• Client_UDP 130.123.123.111 1234
Note: In this demo, the programs have been set to restrict the number of characters that can be sent/received. Max of 50 characters only.

Test the UDP Client-Server Codes

Test the UDP Client-Server Codes Observations
In the simple demo, where a UDP server echoes back the received message (simply converts them in upper case), a single-threaded UDP server is able to communicate quickly with two “simultaneous” UDP clients.
This is because the server is not tied up with any connections. UDP is a connectionless protocol.
Each UDP datagram received by the server contains a sender’s return address (IP address and port number). Therefore, a server may receive multiple datagrams coming from multiple senders.
In comparison, a TCP server can only communicate simultaneously with multiple TCP clients via multithreading.

TCP SERVER & CLIENT s = socket
s = socket bind
loop “forever” {
ns = accept /* by creating newsocket */ /* communicate with client*/
loop until done
send(s, …)
recv(s, …) }
recv(ns, &receive_buffer[n], 1, 0); send(ns, send_buffer,
closesocket(s)
strlen(send_buffer), 0);
closesocket(ns) //newsocket
/* communicate with server*/
loop until done {

syntax: udp_server server_port_num WSAStartup()
getaddrinfo()
s = socket()
Socket type address
UDP Server
Communication session with client(socket)
closesocket(s) WSACleanup()

getaddrinfo()
s = socket()
UDP Client
syntax: udp_client server_ip_address server_port_num WSAStartup()
Socket type
Server’s address and port number
Communication session with server(socket, server’s address info)
closesocket(s) WSACleanup()
implemented in a loop

UDP server-client interaction
SERVER CLIENT
udp_server server_port_num udp_client server_ip_address server_port_num

getaddrinfo(…,&result) s = socket
loop “forever”
getaddrinfo(…,&result) s = socket
loop until done
//get user command…
//generate content of send_buffer
UDP SERVER & CLIENT
blocks and waits for data to arrive
bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0,
(struct sockaddr*)(&remoteaddr),
bytes = sendto(s, send_buffer, strlen(send_buffer),0,
&addrlen);
getnameinfo( ) //extract sender’s identity
result->ai_addr,
//filter receive_buffer…
result->ai_addrlen ); bytes = recvfrom(s,
process_cmd(receive_buffer) //command bytes = sendto(s, send_buffer,
receive_buffer, sizeof(receive_buffer), 0,
strlen(send_buffer),0,
(struct sockaddr *)(&remoteaddr), sizeof(remoteaddr) );
(struct sockaddr *)(&remoteaddr), &addrlen );
}} closesocket(s) closesocket(s)
//process reply…

The following codes were simplified for brevity of discussions. Socket initialisation codes that were discussed previously when we covered TCP socket programming are only discussed briefly here.
Please see the sample codes for the complete implementation.

#elif defined _WIN32
Cross-platform
#if defined __unix__ || defined __APPLE__
#include
#include
#include
#include
#include
#include //used by getnameinfo()
#include
#include //required by getaddrinfo() and special constants #define WSVERS MAKEWORD(2,2)

Required only by Windows
//Create a WSADATA object called wsadata.
WSADATA wsadata;
// Initialize the use of the Windows Sockets DLL before making other
• The WSADATA structure contains information about the Windows Sockets implementation.
// Winsock functions calls.
// This also makes certain that Winsock is supported on the system.
err = WSAStartup(WSVERS, &wsadata);
if (err != 0) { WSACleanup();
• free any resources allocated on behalf of the application.
// Tell the user that we could not find a usable WinsockDLL
printf(“WSAStartup failed with error: %d\n”, err);
exit(1); }

Verify that the Winsock DLL supports the latest version, 2.2.
//**************************************************************************************
/* Confirm that the WinSock DLL supports 2.2. */
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return 2.2 in wVersion since that is the version we requested. */
//**************************************************************************************
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 2) { /* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf(“Could not find a usable version of Winsock.dll\n”); WSACleanup();
exit(1); }
printf(“=================== SERVER ==================\n”); printf(“The Winsock 2.2 dll was found okay.\n”);

struct addrinfo *result = NULL; struct addrinfo hints;
int iResult;
memset(&hints, 0, sizeof(struct addrinfo));
UDP Server
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; // Datagram socket hints.ai_flags = AI_PASSIVE; // For wildcard IP address hints.ai_protocol = IPPROTO_UDP;
iResult = getaddrinfo(NULL, argv[1], &hints, &result);
s = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

UDP Server
// bind the socket to the local address of the machine and port number
iResult = bind( s, result->ai_addr, (int)result->ai_addrlen);
freeaddrinfo(result); //free the memory allocated by the getaddrinfo //function for the server’s address, as it is
//no longer needed

Data structures
#define BUFFER_SIZE 200
char clientHost[NI_MAXHOST]; char clientService[NI_MAXSERV];
UDP Server
char send_buffer[BUFFER_SIZE],receive_buffer[BUFFER_SIZE];
int bytes;
Ws2tcpip.h
/* getnameinfo constants */ #define NI_MAXHOST 1025 #define NI_MAXSERV 32

UDP Server Receiving a datagram: recvfrom()
struct sockaddr_storage clientAddress; //allows ipv4 and ipv6 socklen_t addrlen;
char portNum[NI_MAXSERV];
addrlen = sizeof(clientAddress); //IPv4 & IPv6-compliant
while(1) { //main loop
printf(“the <<>> is waiting to receive commands.\n”); memset(receive_buffer, 0, sizeof(receive_buffer));//clean up receive_buffer
//receive datagram and store the source address.
bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0, (struct sockaddr*)&clientAddress, &addrlen);
if(bytes < 0){ continue; blocks and waits for data to arrive UDP Server Extracting the Sender’s identity: getnameinfo() //******************************************************************** //IDENTIFY UDP client's IP address and port number. //******************************************************************** memset(clientHost, 0, sizeof(clientHost)); memset(clientService, 0, sizeof(clientService)); getnameinfo((struct sockaddr *)&clientAddress, addrlen, clientHost, sizeof(clientHost), clientService, sizeof(clientService), NI_NUMERICHOST); printf("\nReceived a packet of size %d bytes from <<>> with IP address:%s, at Port:%s\n”,bytes,clientHost, clientService); printf(“\tPACKET contents: %s\n”,receive_buffer);

UDP Server: Communication session
while (1) { //main loop
bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0, (struct sockaddr*)&clientAddress,
&addrlen);
getnameinfo(…) //extract human-readable client IP address and port number
while (n < bytes){//EXTRACT one command, delimited by \r\n Receive message, then extract sender’s address details if (bytes < 0) break; if (receive_buffer[n] == '\n') { /*end on a LF*/ receive_buffer[n] = '\0'; removal of message delimeters (\r\n) if (receive_buffer[n] == '\r'){ /*ignore CRs*/ receive_buffer[n] = '\0'; memset(send_buffer, 0, sizeof(send_buffer)); sprintf(send_buffer,"%s %s", "the client typed: ", receive_buffer); addrlen=sizeof(clientAddress); bytes = sendto(s, send_buffer, strlen(send_buffer), 0, Reply message } //end – main loop closesocket(s); WSACleanup(); download udp server & client codes to see (struct sockaddr *)&clientAddress, addrlen); the complete codes 26 WSAStartup() getaddrinfo() Recall the UDP client’s pseudocode (shown here as a guide for the next discussion) s = socket() UDP Client syntax: udp_client server_ip_address server_port_num Socket type Server’s address and port number Communication session with server(socket, server’s address info) closesocket(s) WSACleanup() implemented in a loop Client UDP syntax: udp_client server_ip_address server_port_num clientUDP.cpp struct addrinfo *result=NULL, hints; int iResult; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ //hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = IPPROTO_UDP; hints.ai_canonname = NULL; //full canonical hostname hints.ai_addr = NULL; //struct sockaddr_in or .._in6 hints.ai_next = NULL; //linked list, next node Only for servers //Server’s IP address: get it from argv[1] //Server’s Port number: get it from argv[2] if (argc == 3){ //if there are 3 parameters passed to the argv[] array. sprintf(portNum,"%s", argv[2]); iResult = getaddrinfo(argv[1], portNum, &hints, &result); cout << "connecting to " << argv[1] << endl; printf("USAGE: client_udp IP-address [port]\n"); //missing IP address printf("Using default settings, localhost, Port:1234\n"); sprintf(portNum,"%s", DEFAULT_PORT); iResult = getaddrinfo("localhost", portNum, &hints, &result); // iResult – result from getaddrinfo() clientUDP.cpp if (iResult != 0) { printf("getaddrinfo failed: %d\n", iResult); freeaddrinfo(result); WSACleanup(); return 1; s = INVALID_SOCKET; //socket for listening Client UDP // Create a SOCKET for the server to listen for client connections s = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
//check for errors in socket allocation
if (s == INVALID_SOCKET) {
printf(“Error at socket(): %d\n”, WSAGetLastError()); freeaddrinfo(result);
WSACleanup();
} 29 printf(“\nSOCKET created.\n”);

memset(send_buffer, 0, sizeof(send_buffer));//clean up printf(“\nwaiting for user input…\n”); get_keyboard(send_buffer);
struct sockaddr_storage serverAddress;
clientUDP.cpp
socklen_t addrlen = sizeof(serverAddress);
while (strncmp(send_buffer,”.”,1) != 0) { //SEND
Client UDP
bytes = sendto(s, send_buffer, strlen(send_buffer),0, (result->ai_addr), result->ai_addrlen);
memset(receive_buffer, 0, sizeof(receive_buffer)); //clean up bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0,
(struct sockaddr*)(&serverAddress), &addrlen );
process_received_message(receive_buffer); //user-defined memset(send_buffer, 0, sizeof(send_buffer)); //clean up get_keyboard(send_buffer); //get user input
freeaddrinfo(result); closesocket(s); //close(s); //in Linux WSACleanup();

#define BUFFER_SIZE 200
#define SEGMENT_SIZE 80 //////////////////////////////////////////////////////////////////////////////////////////////////////////////// void get_keyboard(char * send_buffer) {
clientUDP.cpp
if(fgets(send_buffer,SEGMENT_SIZE, stdin) ==NULL){ printf(“fgets() error!\n”);
• Read input from the keyboard
send_buffer[strlen(send_buffer)-1]=’\0′;//strip ‘\n’ strcat(send_buffer,”\r\n”);
printf(“Message length: %d \n”,(int)strlen(send_buffer));
• filter out the ‘\n’ due to fgets()
Client UDP
• lastly, append ‘\r\n\0’
e.g. hello\r\n\0

Send data through a socket:
int sendto(SOCKET s, const char *msg, int msglen, int flags, const struct sockaddr *to, int tolen);
PARAMETERS
s = socket descriptor
msg = a pointer to a buffer
msglen = the length of the buffer
flags = 0 (we will set it to zero for our applications) to=structure of address with the IP / port # tolen=length of the structure
Examples: struct addrinfo *result;
bytes=sendto(s, send_buffer, strlen(send_buffer),0, result->ai_addr, result->ai_addrlen); bytes=sendto(s, send_buffer, strlen(send_buffer), 0,
(struct sockaddr *)&clientAddress, addrlen);

Send data through a socket:
int sendto(SOCKET s, const char *msg, int msglen, int flags, const struct sockaddr *to, int tolen);
Examples: struct addrinfo *result;
bytes=sendto(s, send_buffer, strlen(send_buffer),0, result->ai_addr, result->ai_addrlen); bytes=sendto(s, send_buffer, strlen(send_buffer), 0,
(struct sockaddr *)&clientAddress, addrlen);
Returns number of bytes sent.
If an error occurs during sending, SOCKET_ERROR is returned.

PARAMETERS
recvfrom()
 Receive a datagram and stores the source address.  int recvfrom(SOCKET s, char *msg, int msglen,
int flags, struct sockaddr *from, int *fromlen)
s = socket (inside the socket descriptor: port and IP address…) msg = a pointer to a buffer
msglen = the capacity of the buffer in bytes
from =(optional) structure of address with the IP / port # fromlen=(optional) length of the structure
Example: struct sockaddr_storage remoteaddr;
bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0, (struct sockaddr*)(&remoteaddr), &addrlen );

recvfrom()
 Receive a datagram and stores the source address.  int recvfrom(SOCKET s, char *msg, int msglen,
int flags, struct sockaddr *from, int *fromlen) blocks and waits for data
Example: struct sockaddr_storage remoteaddr;
bytes = recvfrom(s, receive_buffer, sizeof(receive_buffer), 0,
(struct sockaddr*)(&remoteaddr), &addrlen );
Returns number of bytes received.
If bytes is equal to zero, then the peer gracefully shutdown; otherwise, an error is returned (SOCKET_ERROR).

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com