1 / 38

Chapter 6 Fundamentals of Socket Programming Recommended reading: Comer, Vol 3, Chapter 5

Dr. Y.W. Leung. 2. Casting of Data TypesCasting is to change the data type of a variable or expression to the designated one. Example:If i is an int, then the data type of the following expression is double:(double) (i 1)PointersEvery memory location has an addressWe can use this address to

aldis
Download Presentation

Chapter 6 Fundamentals of Socket Programming Recommended reading: Comer, Vol 3, Chapter 5

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. Dr. Y.W. Leung 1 Chapter 6 Fundamentals of Socket Programming (Recommended reading: Comer, Vol 3, Chapter 5) Review of C Programming Some Data Types The following data types are often used in socket programming: u_char unsigned 8-bit character u_short unsigned 16-bit integer u_long unsigned 32-bit integer A structure is a group of different types of data. Example: struct info { char name[20] ; int ID ; }; … struct info student[60] ; student[0].name = "chan" ;11 student[0].ID = 1234 ; student[1].name = "cheung" ; student[1].ID = 5678 ;

    2. Dr. Y.W. Leung 2 Casting of Data Types Casting is to change the data type of a variable or expression to the designated one. Example: If i is an int, then the data type of the following expression is double: (double) (i+1) Pointers Every memory location has an address We can use this address to access the content in this memory location. A pointer is a variable that stores the memory address (not the value) of a data item. Declaration of pointer variable: data-type *pointer-variable; Dereference operator *: *pv gives the content stored in the memory location with address pv. Address operator &: The address storing the first memory byte of the variable v is &v.

    3. Dr. Y.W. Leung 3 Example x and y are declared to be of type "float", and p is declared to be of type "pointer to float": float x, y, *p; The following statements   p = &x ; y = *p ; are equivalent to   y = x ; Pointer and Array The name of an array is actually a pointer to the first element in the array. If x is a one-dimensional array, the address of the 1st array element is &x[0] or x; the address of the 2nd array element is &x[1] or (x+1); Pointer Types The 80x86 memory system is divided into segments, and each segment has 64 K. An address consists of two parts: segment and offset.

    4. Dr. Y.W. Leung 4 Pointer types: A near pointer only stores the offset which is relative to the data segment. A far pointer stores both the segment and offset. Byte Order Different computers may have different internal representation of 16 / 32-bit integer (called host byte order). Examples Big-Endian byte order (e.g., used by Motorola 68000): Little-Endian byte order (e.g., used by Intel 80x86):

    5. Dr. Y.W. Leung 5 TCP/IP specifies a network byte order which is the big-endian byte order. For some WinSock functions, their arguments (i.e., the parameters to be passed to these functions) must be stored in network byte order. WinSock provides functions to convert between host byte order and network byte order: Prototypes for these conversion functions:

    6. Dr. Y.W. Leung 6 Endpoint Address Generic Endpoint Address The socket abstraction accommodates many protocol families. It supports many address families. It defines the following generic endpoint address: ( address family, endpoint address in that family ) Data type for generic endpoint address: TCP/IP Endpoint Address For TCP/IP, an endpoint address is composed of the following items: Address family is AF_INET (Address Family for InterNET). Endpoint address in that family is composed of an IP address and a port number.

    7. Dr. Y.W. Leung 7 The IP address identifies a particular computer, while the port number identifies a particular application running on that computer. The TCP/IP endpoint address is a special instance of the generic one: Port Number A port number identifies an application running on a computer. When a client program is executed, WinSock randomly chooses an unused port number for it. Each server program must have a pre-specified port number, so that the client can contact the server.

    8. Dr. Y.W. Leung 8 The port number is composed of 16 bits, and its possible values are used in the following manner: 0 - 1023: For well-known server applications. 1024 - 49151: For user-defined server applications (typical range to be used is 1024 - 5000). 49152 - 65535: For client programs. Port numbers for some well-known server applications: WWW server using TCP: 80 Telnet server using TCP: 23 SMTP (email) server using TCP: 25 SNMP server using UDP: 161.

    9. Dr. Y.W. Leung 9 Data types for TCP/IP endpoint address: struct in_addr { u_long s_addr ; /* IP address */ }; The IP address is stored in a structure instead of an unsigned long (with 32 bits) because of a historical reason. sockaddr and sockaddr_in are compatible: If you only use TCP/IP, you can use sockaddr_in without using sockaddr.

    10. Dr. Y.W. Leung 10 Example 1 The IP address of a server is 158.182.7.63. Its decimal value is 2662729535. We can specify the endpoint address for this server as follows: struct sockaddr_in ServerAddr; … ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = 2000; ServerAddr.sin_addr.s_addr = htonl (2662729535); Example 2 We specify the endpoint address for a server as follows: struct sockaddr_in ServerAddr; … ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = 2000; ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); where the symbolic constant INADDR_ANY represents a wildcard address that matches any of the computer's IP address(es).

    11. Dr. Y.W. Leung 11 Sketch of a TCP Client and a TCP Server Using TCP, both the client and the server use three major steps for communication: Initialize sockets. Communicate between sockets. Close the sockets. In this section, we study the above three steps in detail. Remark Network communication may be considered as network I/O. The above steps are similar to that for file I/O: Open a file. Read and write data. Close the file. Initialize Sockets There are three initialization steps: Initialize WinSock DLL. Create a socket. Assign an endpoint address to a socket.

    12. Dr. Y.W. Leung 12 Initialize WinSock DLL Before using WinSock, an application calls WSAStartup(). Then Windows binds to the WinSock DLL and allocates the necessary resources to this application. WSAStartup() requires two arguments: The 1st argument specifies the version of the requested WinSock. The 2nd argument returns information about the version of the WinSock that is actually used.

    13. Dr. Y.W. Leung 13 Example #define WSVERS MAKEWORD(2, 0) … WSADATA wsadata ; … WSAStartup ( WSVERS, &wsadata );

    14. Dr. Y.W. Leung 14 Create a Socket A program calls socket() to create a new socket, which can then act as the endpoint of the TCP connection. The function socket() requires three arguments: The 1st argument is the the protocol family. For TCP/IP, specify PF_INET (Protocol Family for the InterNET). The 2nd argument is the type of socket to be created. For stream (TCP) sockets, specify SOCK_STREAM. The 3rd argument is simply 0. The call to socket() returns a socket descriptor for the newly created socket.

    15. Dr. Y.W. Leung 15 Example SOCKET s; … s = socket( PF_INET, SOCK_STREAM, 0 );

    16. Dr. Y.W. Leung 16 Assign an Endpoint Address to a Socket After creating a socket, a server must assign its endpoint address to this socket. Then the client can identify the server's socket and send requests to this server. Steps The server specifies its endpoint address. In other words, it assigns the following three attribute values to a structure of type sockaddr_in: protocol family (AF_INET for TCP/IP), IP address, port number. The server calls bind() to bind its endpoint address to the newly created socket.

    17. Dr. Y.W. Leung 17 Example struct sockaddr_in ServerAddr; … /* Specify the server's endpoint address in ServerAddr here */ … bind ( s, (struct sockaddr *) &ServerAddr, sizeof(ServerAddr) );

    18. Dr. Y.W. Leung 18 Communicate Between Sockets Main Steps Setup a TCP connection: A client initiates to setup a TCP connection to a server. The server waits for and accepts connection requests from the clients. Send and receive data. Close the TCP connection. In socket programming, a TCP connection and its associated socket are closed simultaneously. Therefore, we will consider the 3rd step in the next subsection. Client Initiates a TCP Connection After creating a socket, a client calls connect() to establish a TCP connection to a server. The function connect() has three arguments: the descriptor of the client's socket; endpoint address of the server; length of the 2nd argument.

    19. Dr. Y.W. Leung 19 Example struct sockaddr_in ServerAddr; … /* Specify the server's endpoint address in ServerAddr here */ … connect ( s, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );

    20. Dr. Y.W. Leung 20 Server Listens to Connection Requests After creating a socket, the server calls listen() to place this socket in passive mode. Then the socket listens and accepts incoming connection requests from the clients. Multiple clients may send requests to a server. The function listen() tells the OS to queue the connection requests for the server's socket. The function listen() has two arguments: the server's socket; the maximum size of the queue. The function listen() applies only to sockets used with TCP.

    21. Dr. Y.W. Leung 21 Example listen(s, 1);

    22. Dr. Y.W. Leung 22 Server Accepts a Connection Request The server calls accept() to extract the next incoming connection request from the queue. Then the server creates a new socket for this connection request and returns the descriptor of this new socket. Remarks The server uses the new socket for the new connection only. When this connection ends, the server closes this socket. The server still uses the original socket to accept additional connection requests. The function accept() applies only to stream (TCP) sockets.

    23. Dr. Y.W. Leung 23 Example struct sockaddr_in ClientAddr; int len; SOCKET nsock; … len = sizeof ( ClientAddr ); nsock = accept( s, (struct sockaddr *)&ClientAddr, &len );

    24. Dr. Y.W. Leung 24 Send Data Both client and server calls send() to send data across a connection. The function send() copies the outgoing data into buffers in the OS kernel, and allows the application to continue execution while the data is being sent across the network. If the buffers become full, the call to send() may block temporarily until free buffer space is available for the new outgoing data.

    25. Dr. Y.W. Leung 25 Example char *message="Hello world!"; … send(s, message, strlen(message), 0);

    26. Dr. Y.W. Leung 26 Receive Data Both the client and server call recv() to receive data through a TCP connection. Before calling recv(), the application must allocate a buffer for storing the data to be received. The function recv() extracts the data that has arrived at the specified socket, and copies them to the application's buffer. Two possible cases: Case 1: No data has arrived The call to recv() blocks until data arrives. Case 2: Data has arrived If the incoming data can fit into the application's buffer, recv() extracts all the data and returns the number of bytes received. Otherwise, recv() only extracts enough to fill the buffer. Then it is necessary to call recv() a number of times in order to receive the entire message. (See the next chapter.)

    27. Dr. Y.W. Leung 27 Example: receive a small message with at most 5 characters char buf[5], *bptr; int buflen; … bptr = buf; buflen = 5; recv(s, bptr, buflen, 0);

    28. Dr. Y.W. Leung 28 Close the Sockets Close a Socket Once a client or server finishes using a socket, it calls closesocket() to terminate the TCP connection associated with this socket, and deallocate this socket. Example closesocket(s);

    29. Dr. Y.W. Leung 29 Clean Up When an application finishes using sockets, it must call WSACleanup() to deallocate all data structures and socket bindings. Example WSACleanup();

    30. Dr. Y.W. Leung 30 Sequence of Execution of WinSock Functions We assume that TCP is used and the server serves the clients’ requests one after the other. Sequence of execution of WinSock functions:

    31. Dr. Y.W. Leung 31 Remarks on WinSock Functions WinSock has defined some data structures that can be used in WinSock programs. Examples sockaddr sockaddr_in WinSock has defined some symbolic constants that can be used as arguments to WinSock functions. Examples AF_INET PF_INET INADDR_ANY SOCK_STREAM (stream socket) SOCK_DGRAM (datagram socket) To use these symbolic constants and declarations, include the header file winsock.h or winsock2.h: #include <winsock.h> or #include <winsock2.h>

    32. Dr. Y.W. Leung 32 A Simple and Complete Example In this section, we implement the following client-server application using TCP: The client sends the message "Hello" to the server. The server sends this message back to the client. Then both the client and server are terminated. Client Program #include <stdio.h> #include <winsock2.h>   #define WSVERS MAKEWORD(2,0)   main() { WSADATA wsadata; SOCKET s; struct sockaddr_in ServerAddr; char *message="Hello", buf[5], *bptr; int i, buflen, count;   /* call WSAStartup() and socket() */ WSAStartup ( WSVERS , &wsadata ) ; s = socket ( PF_INET , SOCK_STREAM , 0 );

    33. Dr. Y.W. Leung 33 /* call connect() to connect to the server */ ServerAddr.sin_family = AF_INET ; ServerAddr.sin_port = htons(2000) ; ServerAddr.sin_addr.s_addr = htonl(2662729535); connect(s, (struct sockaddr *) &ServerAddr, sizeof(ServerAddr));    /* call send() to send a message to the server */ send(s, message, strlen(message), 0);   /* call recv() to receive a message from the server */ bptr = buf; buflen = 5; recv(s, bptr, buflen, 0);   /* Echo the received message from the server */ for (i=0; i<5; ++i){ printf("%c", buf[i]); } printf("\n%s\n", "Bye bye!");   /* call closesocket() */ closesocket(s);   /* call WSACleanup() */ WSACleanup(); }

    34. Dr. Y.W. Leung 34 Server Program #include <stdio.h> #include <winsock2.h> #define WSVERS MAKEWORD(2,0)   main() { WSADATA wsadata; SOCKET s, nsock; struct sockaddr_in ServerAddr, ClientAddr; char buf[5], *bptr; int i, buflen, count;   /* call WSAStartup() */ WSAStartup ( WSVERS , &wsadata ) ;   /* call socket() */ s = socket ( PF_INET , SOCK_STREAM , 0 );   /* call bind() */ ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(2000); ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); bind ( s, (struct sockaddr *) &ServerAddr , sizeof(ServerAddr) );   /* call listen() */ listen(s,1);  

    35. Dr. Y.W. Leung 35 /* call accept() */ i = sizeof ( ClientAddr ); nsock = accept (s, (struct sockaddr *) &ClientAddr , &i );    /* call recv() to receive a message from the client */ bptr = buf; buflen = 5; recv ( nsock , bptr , buflen , 0 );   /* call send() to send the message back to the client */ send ( nsock, buf, strlen(buf), 0);   /* call closesocket() */ closesocket ( nsock ); closesocket ( s );   /* call WSACleanup() */ WSACleanup(); }

    36. Dr. Y.W. Leung 36 Remarks For clarity, the above two programs do not check any possible error in network communication (e.g., whether the remote server can be reached). In practice, a sophisticated program should check all the possible errors. If a program has to receive a large message, it should call recv() repeatedly until the entire message has been received. The details are explained in the next chapter.

    37. Dr. Y.W. Leung 37 Tutorial Problems Using the network byte order, how is the IP address 158.182.7.1 stored in the memory? State the items in a generic endpoint address. State the items in a TCP/IP endpoint address. What is the relationship between the above two addresses? A WinSock application has to call both WSAStartup() and socket() for initialization. What is the difference between these two functions? When should an application call closesocket()? When should an application call WSACleanup()? What is the main purpose of bind() ? Should a TCP client call bind()? Should a TCP server call bind()? Consider a TCP client-server application. Should the client call connect() ? Should the server call connect() ?

    38. Dr. Y.W. Leung 38 What are the main purposes of listen() ? What are the main purposes of accept() ? In different executions of a server, is its port number always the same? In different executions of a client, is its port number always the same? When you write a server program, should you assign a port number to it? When you write a client program, should you assign a port number to it? A program calls send() to send a message. When the call returns, does it mean that the entire message has been sent out? A program calls recv() to receive a message. When the call returns, does it mean that the entire message has been received? If you want to develop a server that can store 100 waiting requests, how would you do?

More Related