Windows Socket Modern System Calls & Concurrent, Connection-Oriented Servers. Prof. Lin Weiguo Copyleft 2009~2015, College of Computing, CUC

Similar documents
Modern System Calls(IPv4/IPv6)

Writing Network Applications using the TCP/IP Protocol Stack: Socket Programming

TCP Network Programming in C

CSE 333 SECTION 6. Networking and sockets

CSE 333 SECTION 7. Client-Side Network Programming

CSE 333 SECTION 8. Sockets, Network Programming

CSE 333 SECTION 7. Client-Side Network Programming

CSE 333 SECTION 7. C++ Virtual Functions and Client-Side Network Programming

CSE 333 Section 3. Thursday 12 April Thursday, April 12, 12

TCP/IP Sockets in C: Practical Guide for Programmers. Computer Chat. Internet Protocol (IP) IP Address. Transport Protocols. Ports

CS 3516: Computer Networks

Network Programming Week #1. K.C. Kim

5. System Calls or Bust

UNIX System Programming Lecture 19: IP Sockets

The Berkeley Sockets API. Networked Systems Architecture 3 Lecture 4

2007 Microsoft Corporation. All rights reserved.

Sockets. TCP/IP Sockets in C: Practical Guide for Programmers (we are covering all chapters of Part 1; Part 2 is a good sockets API reference)

Outline. Option Types. Socket Options SWE 545. Socket Options. Out-of-Band Data. Advanced Socket. Many socket options are Boolean flags

Network Programming in C: The Berkeley Sockets API. Networked Systems 3 Laboratory Sessions

Network Programming in C. Networked Systems 3 Laboratory Sessions and Problem Sets

Network Socket Programming - 3 BUPT/QMUL

TCP Echo Application: Client & Server. TA: Awad A Younis Class: CS457 Fall 2014

Network Socket Programming - 3 BUPT/QMUL

IP Addresses, DNS. CSE 333 Spring Instructor: Justin Hsia

CS 640: Computer Networking

TCP/IP Sockets in C: Practical Guide for Programmers. Computer Chat. Internet Protocol (IP) IP Address. Transport Protocols

CS321: Computer Networks Socket Programming

IP Addresses, DNS. CSE 333 Summer Teaching Assistants: Renshu Gu William Kim Soumya Vasisht

Introduction to Computer Networks

Lecture 7. Followup. Review. Communication Interface. Socket Communication. Client-Server Model. Socket Programming January 28, 2005

CSE 333 Section 8 - Client-Side Networking

CSE 124 Discussion Section Sockets Programming 10/10/17

CS321: Computer Networks Introduction to Application Layer

Hyo-bong Son Computer Systems Laboratory Sungkyunkwan University

Lecture 3 Overview! Last Lecture! TCP/UDP and Sockets introduction!

Sockets. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

CSE 333 Lecture 16 - network programming intro

IPv6 Porting Applications

CS 43: Computer Networks. 05: Socket Programming September 12-14, 2018

Winsock Server adding Multiple clients support C++

Socket Programming. CSIS0234A Computer and Communication Networks. Socket Programming in C

Computer Network Programming

PA #2 Reviews. set_name, get_name, del_name. Questions? Will be modified after PA #4 ~

Ports under 1024 are often considered special, and usually require special OS privileges to use.

Unix Network Programming

Introduction to Client-Server Model

UNIX Sockets. Developed for the Azera Group By: Joseph D. Fournier B.Sc.E.E., M.Sc.E.E.

CSE 333 Lecture network programming intro

Category: Informational J. Bound J. McCann Hewlett-Packard W. Stevens February 2003

UNIX Network Programming. Overview of Socket API Network Programming Basics

목포해양대해양컴퓨터공학과. IPv6 적용

Sockets and Parallel Computing. CS439: Principles of Computer Systems April 11, 2018

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

Socket Programming(2/2)

last time redo logging copy-on-write filesystems / snapshots distributed systems motivation, etc.

CSCI 4061: Sockets and Network Programming

Network programming(i) Lenuta Alboaie

Unix Network Programming Chapter 4. Elementary TCP Sockets 광운대학교컴퓨터과학과 정보통신연구실 석사과정안중현

Client-server model The course that gives CMU its Zip! Network programming Nov 27, Using ports to identify services.

CSC209H Lecture 9. Dan Zingaro. March 11, 2015

UNIT IV- SOCKETS Part A

CSE 333 Lecture 8 - file and network I/O

sottotitolo Socket Programming Milano, XX mese 20XX A.A. 2016/17 Federico Reghenzani

CLIENT-SIDE PROGRAMMING

Socket Programming TCP UDP

Introduction to Lab 2 and Socket Programming. -Vengatanathan Krishnamoorthi

Application Layer. Application Layer. QoS and Network Policies. Quality of Service (QoS)

Outline. Distributed Computer Systems. Socket Basics An end-point for a IP network connection. Ports. Sockets and the OS. Transport Layer.

Outline. Distributed Computing Systems. Socket Basics (1 of 2) Socket Basics (2 of 2) 3/28/2014

1.2 The first Internet (i.e., one of the first packet switched networks) was referred to as the ARPANET.

Socket Programming. Dr. -Ing. Abdalkarim Awad. Informatik 7 Rechnernetze und Kommunikationssysteme

Azblink API for Sending XMPP Messages via HTTP POST

Client-side Networking

Redesde Computadores(RCOMP)

A. Basic Function Calls for Network Communications

Lecture 5 Overview! Last Lecture! This Lecture! Next Lecture! I/O multiplexing! Source: Chapter 6 of Stevens book!

Hybrid of client-server and P2P. Pure P2P Architecture. App-layer Protocols. Communicating Processes. Transport Service Requirements

Network Programming November 3, 2008

Network Programming Worksheet 2. Simple TCP Clients and Servers on *nix with C.

Review. Preview. Closing a TCP Connection. Closing a TCP Connection. Port Numbers 11/27/2017. Packet Exchange for TCP Connection

Oral. Total. Dated Sign (2) (5) (3) (2)

Inter-Process Communication. Disclaimer: some slides are adopted from the book authors slides with permission 1

The BSD UNIX Socket Interface (CS 640 Lecture) Assignment 1. Interprocess Communication (IPC) Work Individually (no groups)

Server-side Programming

WinSock. What Is Sockets What Is Windows Sockets What Are Its Benefits Architecture of Windows Sockets Network Application Mechanics

Introduction to Socket Programming

Piotr Mielecki Ph. D.

A Socket Example. Haris Andrianakis & Angelos Stavrou George Mason University

Session NM056. Programming TCP/IP with Sockets. Geoff Bryant Process software

ECE 435 Network Engineering Lecture 2

NETWORK PROGRAMMING. Instructor: Junaid Tariq, Lecturer, Department of Computer Science

COE 4DN Advanced Internet Communications. Basic Sockets in C (with some Java and Python) version 1, 2015

Elementary TCP Sockets

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

Network programming(ii) Lenuta Alboaie

Outline. Operating Systems. Socket Basics An end-point for a IP network connection. Ports. Network Communication. Sockets and the OS

// print product names in alphabetical order with total // number sold of each product using format name: total void PrintTotals();

STUDY OF SOCKET PROGRAMMING

TCP: Three-way handshake

Porting IPv4 applications to IPv4/v6 dual stack. Owen DeLong

Transcription:

Windows Socket Modern System Calls & Concurrent, Connection-Oriented Servers Prof. Lin Weiguo Copyleft 2009~2015, College of Computing, CUC Nov 2015

Note } You should not assume that an example in this presentation is complete. Items may have been selected for illustration. It is best to get your code examples directly from the textbook and modify them to work. Use the lectures to understand the general principles. 2 Advanced Windows Network Programming

Outline } Windows Socket Modern System Calls } Concurrent, Connection-Oriented Servers 3 Advanced Windows Network Programming

IP v6 (RFC 2460) The IPv6 fixed header 4 Advanced Windows Network Programming

Winsock Headers and Libraries } Include files: winsock2.h } Library files: ws2_32.lib //winsock 2.2 #include <winsock2.h> //TCP/IP specific extensions in Windows Sockets 2 #include <ws2tcpip.h> #pragma comment(lib, ws2_32.lib ") 5 Advanced Windows Network Programming

IPv6 Address Structure } 28-byte sockaddr_in6 // (IPv6 only--see struct sockaddr_in and struct in_addr for IPv4) struct sockaddr_in6 { u_int16_t sin6_family; // address family, AF_INET6 u_int16_t sin6_port; // port number, Network Byte Order u_int32_t sin6_flowinfo; // IPv6 flow information struct in6_addr sin6_addr; // IPv6 address u_int32_t sin6_scope_id; // Scope ID }; struct in6_addr { unsigned char s6_addr[16]; // IPv6 address }; 6 Advanced Windows Network Programming

InetPton Function } The InetPton function is supported on Windows Vista and later. } The InetPton function provides a protocol-independent conversion of an IP address in its standard text presentation form into its numeric binary form. int InetPton ( INT Family, //[in] The address family. PCTSTR pszaddrstring, //[in] NULL-terminated string PVOID paddrbuf //[out] buffer in which to store the numeric IP address ); struct sockaddr_in sa; // IPv4 struct sockaddr_in6 sa6; // IPv6 InetPton(AF_INET, "192.0.2.1", &(sa.sin_addr)); // IPv4 InetPton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr)); // IPv6 7 Advanced Windows Network Programming

InetNtop function } provides a protocol-independent address-to-string int translation InetNtop( ); INT Family, //[in] The address family. PVOID paddr, //[in] IP address in network byte to convert to a string PTSTR pstringbuf //[out] a buffer in which to store the NULL-terminated string //representation of the IP address size_t StringBufSize //[in] the length of the pstringbuf. char ip4[inet_addrstrlen]; // space to hold the IPv4 string struct sockaddr_in sa; // pretend this is loaded with something InetNtop(AF_INET, &(sa.sin_addr), ip4, INET_ADDRSTRLEN); printf("the IPv4 address is: %s\n", ip4); char ip6[inet6_addrstrlen]; // space to hold the IPv6 string struct sockaddr_in6 sa6; // pretend this is loaded with something InetNtop(AF_INET6, &(sa6.sin6_addr), ip6, INET6_ADDRSTRLEN); printf("the address is: %s\n", ip6); 8 Advanced Windows Network Programming

Prep the socket address structures for connection } Prepare for a client who wants to connect to a particular server, say "www.microsoft.com" port 3490. char *hostname= "www.microsoft.com"; char *port = "3490"; struct addrinfo *result = NULL; struct addrinfo *ptr = NULL; struct addrinfo hints; // Setup the hints address info structure // which is passed to the getaddrinfo() function ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; getaddrinfo(hostname, port, &hints, &result); // Retrieve each address and print out the hex bytes for(ptr=result; ptr!= NULL ;ptr=ptr->ai_next) {.} freeaddrinfo(result); 9 Advanced Windows Network Programming

struct addrinfo } Used as parameters in getaddrinfo() } In each returned addrinfo structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfo structure points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member. struct addrinfo { int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc. int ai_family; // AF_INET, AF_INET6, AF_UNSPEC int ai_socktype; // SOCK_STREAM, SOCK_DGRAM int ai_protocol; // use 0 for "any" size_t ai_addrlen; // size of ai_addr in bytes struct sockaddr *ai_addr; // struct sockaddr_in or _in6 char *ai_canonname; // full canonical hostname struct addrinfo *ai_next; // linked list, next node }; } Header : #include "ws2tcpip.h" 10 Advanced Windows Network Programming

struct sockaddr } The socket abstraction accommodates many protocol families. } It supports many address families(af_inet (IPv4) or AF_INET6 (IPv6) ). } It defines the following generic endpoint address: ( address family, endpoint address in that family ) } Data type for generic endpoint address: //cast to switch between the two types struct sockaddr { unsigned short sa_family; //type of address char sa_data[14]; //value of address }; } sockaddr and sockaddr_in are compatible 11 Advanced Windows Network Programming

Generic Address Storage } struct sockaddr_storage, 128bytes struct sockaddr_storage { sa_family_t ss_family; // address family // all this is padding, implementation specific, ignore it: cast it to a struct sockaddr_in or sockaddr_in6 char ss_pad1[_ss_pad1size]; int64_t ss_align; char ss_pad2[_ss_pad2size]; }; } Ws2def.h (include Winsock2.h); 12 Advanced Windows Network Programming 11/27/15

Adaptive Programming with IPv4/IPv6 1 struct sockaddr_storage addr; 2 memset(&addr, 0, sizeof(struct sockaddr_storage)); 3 if (isipv6 == TRUE) 4 { 5 struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; 6 addr_v6->sin6_family = AF_INET6; 7 addr_v6->sin6_port = 1234; 8 inet_pton(af_inet6, 2001:3211::1, &(addr_v6->sin6_addr)); 9 } 10 else 11 { 12 struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; 13 addr_v4->sin_family = AF_INET; 14 addr_v4->sin_port = 1234; 15 inet_aton( 192.168.1.228, &(addr_v4->sin_addr)); 16 } 17 18 sendto(sock, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage)); 13 Advanced Windows Network Programming

getaddrinfo() } The getaddrinfo function provides protocolindependent translation from an ANSI host name to an address. int getaddrinfo( //Success returns zero. in const char *nodename, //a host (node) name or a numeric host address string // e.g. "www.example.com" or IP in const char *servname, //a service name or port number represented as a string. // e.g. "http" or port number in const struct addrinfo *hints, //hints about the type of socket the caller supports out struct addrinfo **res //a linked list of one or more addrinfo structures that contains //response information about the host ); 14 Advanced Windows Network Programming

Example for a server } Prepare for a server who wants to listen on your host's IP address, port 3490. int status; struct addrinfo hints; struct addrinfo *servinfo; // will point to the results memset(&hints, 0, sizeof(hints)); // make sure the struct is empty hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6 hints.ai_socktype = SOCK_STREAM; // TCP stream sockets hints.ai_flags = AI_PASSIVE; // fill in my IP for me if ((status = getaddrinfo(null, "3490", &hints, &servinfo))!= 0) { fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); exit(1); } // servinfo now points to a linked list of 1 or more struct addrinfos //... do everything until you don't need servinfo anymore... freeaddrinfo(servinfo); // free the linked-list 15 Advanced Windows Network Programming

Show IPv4/IPv6 Address Example struct addrinfo hints, *res, *p; int status; char ipstr[inet6_addrstrlen]; if (argc!= 2) { fprintf(stderr,"usage: showip hostname\n"); return 1; } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(argv[1], NULL, &hints, &res))!= 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); return 2; } printf("ip addresses for %s:\n\n", argv[1]); for(p = res;p!= NULL; p = p->ai_next) { void *addr; char *ipver; if (p->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; addr = &(ipv4->sin_addr); ipver = "IPv4"; } else { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; addr = &(ipv6->sin6_addr); ipver = "IPv6"; } InetNtop(p->ai_family, addr, ipstr, sizeof ipstr); // convert the IP to a string printf(" %s: %s\n", ipver, ipstr); } Advanced Windows Network Programming freeaddrinfo(res); // free the linked list

socket() SOCKET socket ( int af, //address family: AF_INET, AF_INET6 int type, // socket type: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW int protocol // default 0 ); int s; struct addrinfo hints, *res; // do the lookup // [pretend we already filled out the "hints" struct] getaddrinfo("www.example.com", "http", &hints, &res); // [again, you should do error-checking on getaddrinfo(), and walk // the "res" linked list looking for valid entries instead of just // assuming the first one is good (like many of these examples do.) // See the section on client/server for real examples.] s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 17 Advanced Windows Network Programming

bind() } Ex: binds the socket to the host, running on port 3490 struct addrinfo hints, *res; SOCKET m_hsocket; // first, load up address structs with getaddrinfo(): memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // fill in my IP for me getaddrinfo(null, "3490", &hints, &res); // make a socket: m_hsocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); // bind it to the port we passed in to getaddrinfo(): bind(m_hsocket, res->ai_addr, res->ai_addrlen); Note: By using the AI_PASSIVE flag, I'm telling the program to bind to the IP of the host it's running on. If you want to bind to a specific local IP address, drop the AI_PASSIVE and put an IP address in for the first argument to getaddrinfo(). 18 Advanced Windows Network Programming

Address already in use? } rerun a server and bind() fails, Address already in use } a socket that was connected is still hanging around in the kernel,and it's hogging the port. } You can either wait for it to clear (a minute or so), or add code to your program allowing it to reuse the port, like this: int yes=1; // lose the pesky "Address already in use" error message if (setsockopt(listener,sol_socket,so_reuseaddr,&yes,sizeof(int)) == SOCKET_ERROR) { printf( " setsockopt failed with error %d\n", WSAGetLastError()); } 19 Advanced Windows Network Programming

Retrieves a socket option: getsockopt() int getsockopt( in SOCKET s, // a socket. in int level, //The level at which the option is defined. //Example: SOL_SOCKET, IPPROTO_TCP in int optname, //The socket option for which the value is to be retrieved. //Example: SO_ACCEPTCONN. //The optname value must be a socket option defined within the //specified level, or behavior is undefined. out char *optval, // buffer in which the value for the requested option is to be returned. inout int *optlen // the size of the optval buffer. ); int nerrocode; int nbuflen; int noptlen=sizeof(nbuflen); nerrcode=getsocketopt(s,sol_socket,so_rcvbuf,(char *)&nbuflen,&noptlen); if (nerrcode==socket_error) { } 20 Advanced Windows Network Programming

Sets a socket option: setsockopt int setsockopt( in SOCKET s, // a socket. in int level, // The level at which the option is defined in int optname, // The socket option for which the value is to be set //(for example, SO_BROADCAST) in const char *optval, // the buffer in which the value for the requested option is specified. in int optlen // The size of the buffer pointed to by the optval parameter. ); } Example: set receiving buffer int nerrocode; int nbuflen; int noptlen=sizeof(nbuflen); nbuflen *=10; //set the buffer 10 times of the original nerrcode=setsocketopt(s,sol_socket,so_rcvbuf,(char *)&nbuflen,&noptlen); if (nerrcode==socket_error) { } 21 Advanced Windows Network Programming

Optname @ level = SOL_SOCKET Value Type Meaning SO_BROADCAST BOOL Enables transmission and receipt of broadcast messages on the socket. Enables sockets to delay the acknowledgment of a connection until after the SO_CONDITIONAL_ACCEPT BOOL WSAAccept condition function is called. Does not block close waiting for unsent data to be sent. Setting this option is SO_DONTLINGER BOOL equivalent to setting SO_LINGER with l_onoff set to zero. Disable routing: send directly to an interface. When this option is set, it succeeds SO_DONTROUTE BOOL but is ignored for both AF_INET and AF_INET6 sockets. This option is not supported on ATM sockets (results in an error). SO_KEEPALIVE BOOL Sends keep-alives. Not supported on ATM sockets (results in an error). SO_LINGER LINGER Lingers on close if unsent data is present. Receives OOB data in the normal data stream. For a discussion of this topic, see SO_OOBINLINE BOOL Protocol Independent Out-Of-band Data. Specifies the total per-socket buffer space reserved for receives. This is unrelated to SO_RCVBUF int SO_MAX_MSG_SIZE and does not necessarily correspond to the size of the TCP receive window. Allows the socket to be bound to an address that is already in use. For more SO_REUSEADDR BOOL information, see bind. Not applicable on ATM sockets. SO_EXCLUSIVEADDRUSE BOOL Enables a socket to be bound for exclusive access. Does not require administrative privilege. SO_SNDBUF int Specifies the total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond to the size of a TCP send window.. SO_UPDATE_ACCEPT_CONT EXT int Updates the accepting socket with the context of the listening socket. 22 Advanced Windows Network Programming

connect() struct addrinfo hints, *res; SOCKET m_hsocket; // first, load up address structs with getaddrinfo(): memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; getaddrinfo("www.example.com", "3490", &hints, &res); // make a socket: m_hsocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); // connect! connect(m_hsocket, res->ai_addr, res->ai_addrlen); 23 Advanced Windows Network Programming

listen() } The listen function places a socket in a state in which it is listening for an incoming connection. //int listen(int sockfd, int backlog); listen(m_hsocket,5); } Note:backlog is the number of connections allowed on the incoming queue. Incoming connections are going to wait in this queue until you accept() them and this is the limit on how many can queue up. Most systems silently limit this number to about 20; you can probably get away with setting it to 5 or 10. 24 Advanced Windows Network Programming

accept() struct sockaddr_storage their_addr; socklen_t addr_size; struct addrinfo hints, *res; SOCKET m_hlistensocket, m_hacceptedsocket; //!! don't forget your error checking for these calls!! // first, load up address structs with getaddrinfo(): memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // fill in my IP for me getaddrinfo(null, MYPORT, &hints, &res); // #define MYPORT "3490" // make a socket, bind it, and listen on it: m_hlistensocket= socket(res->ai_family, res->ai_socktype, res->ai_protocol); bind(m_hlistensocket, res->ai_addr, res->ai_addrlen); listen(m_hlistensocket, BACKLOG); // #define BACKLOG 10 // now accept an incoming connection: addr_size = sizeof their_addr; m_haccepedsocket= accept(m_hlistensocket, (struct sockaddr *)&their_addr, &addr_size); // ready to communicate on socket descriptor m_haccepedsocket! 25 Advanced Windows Network Programming

send() and recv() } send() returns the number of bytes actually sent out } this might be less than the number you told it to send! } recv() returns the number of bytes actually read into the buffer } recv() can return 0. This can mean the remote side has closed the connection on you! //int send(socket s, const void *buf, int len, int flags); char *msg = Hello,World!"; int len, bytes_sent; len = strlen(msg); bytes_sent = send(m_hsocket, msg, len, 0); //int recv(socket s, void *buf, int len, int flags); 26 Advanced Windows Network Programming

sendto() and recvfrom() for DGRAM } sendto() returns the number of bytes actually sent int sendto(socket s, const void *buf, int len, int flags, const struct sockaddr *to, int tolen); } recvfrom() returns the number of bytes received int recvfrom(socket s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen ); Note: to/from is a pointer to a remote/local struct sockaddr_storage that will be filled with the IP address and port of the originating machine. Tolen/fromlen is a pointer to a remote/local int that should be initialized to sizeof *to/from or sizeof(struct sockaddr_storage). When the function returns, tolen/fromlen will contain the length of the address actually stored in from. 27 Advanced Windows Network Programming

closesocket() and shutdown() } The closesocket function closes an existing socket. int closesocket(socket s ); } The shutdown function disables sends or receives on a socket. int shutdown(socket s, int how ); SD_SEND0 SD_RECEIVE1 SD_BOTH2 Shutdown send operations. Shutdown receive operations. Shutdown both send and receive operations. 28 Advanced Windows Network Programming

getpeername, getsockname } The getpeername function retrieves the address of the peer to which a socket is connected. int getpeername(socket s, struct sockaddr *name, int *namelen ); Note: Once you have the address, you can use inet_ntop(), getnameinfo(), or gethostbyaddr() to print or get more information. } The getsockname function retrieves the local name for a socket. int getsockname(socket s, struct sockaddr *name, int *namelen ); 29 Advanced Windows Network Programming

Concurrent, Connection-Oriented Servers Ch11, Comers & Stevens, Volume III 30 Advanced Windows Network Programming

Pros of Blocking } Easy to program - Blocking is very easy to program. All user code can exist in one place, and in a sequential order. } Easy to port to Unix - Since Unix uses blocking sockets, portable code can be written easily. } Work well in threads - Since blocking sockets are sequential they are inherently encapsulated and therefore very easily used in threads. 31 Advanced Windows Network Programming

Cons of Blocking } User Interface "Freeze" with clients } Blocking socket calls do not return until they have accomplished their task. When such calls are made in the main thread of an application, the application cannot process the user interface messages. This causes the User Interface to "freeze" because the update, repaint and other messages cannot be processed until the blocking socket calls return control to the applications message processing loop. 32 Advanced Windows Network Programming

Threading } Threading is almost always used with blocking sockets. Non-blocking sockets can be threaded as well, but they require some extra handling and their advantages are lost with blocking sockets. Threading will be discussed briefly as it is important in writing blocking socket servers. Threading can also be used to write advanced blocking clients. 33 Advanced Windows Network Programming

Threading Advantages } Prioritization - Individual threads priorities can be adjusted. This allows individual server tasks or individual connections to be given more or less CPU time. } Encapsulation - Each connection will be contained and less likely to interfere with other connections. } Security - Each thread can have different security attributes. } Multiple Processors - Threading automatically will take advantage of multiple processors. } No Serialization - Threading provides true concurrency. Without threading all requests must be handled by a single thread. For this to work each task to be performed must be broken up into small pieces that can always execute quickly. If any task part blocks or takes time to execute all other task parts will be put on hold until it is complete. After each task part is complete, the next one is processed, etc. With threading, each task can be programmed as a complete task and the operating system will divide CPU time among the tasks. 34 Advanced Windows Network Programming

Thread Pooling } Instead of creating and destroying threads on demand, threads are borrowed from a list of inactive but already created list (pool). } When a thread is no longer needed it is redeposited into the pool instead of being destroyed. While threads are in the pool they are marked inactive and thus do not consume CPU cycles. For a further improvement, the size of the pool can be adjusted dynamically to meet the current needs of the system. 35 Advanced Windows Network Programming

Iterative Vs. Concurrent Implementations } Iterative Servers } Requires a client to wait while it handles prior requests } Long service requests (i.e. transferring a large file) could cause a excessive response delays } Concurrent Servers } Prevents a single client from holding all resources } Allows communication with multiple clients simultaneously } Concurrent servers offer better response times than an iterative server 36 Advanced Windows Network Programming

Process Structure master Server application processes (or threads) slave 1 slave 2 slave n Socket for connection requests Socket for individual requests Operating system The thread structure of a concurrent, connection-oriented server. A master server thread accepts each incoming connection, and creates a slave thread to handle it. 37 Advanced Windows Network Programming

Echo Server: Thread Function Example void tcpechod(socket fd){ char buf[maxline]; int n; n = recv(fd, buf, sizeof buf, 0); while (n!= SOCKET_ERROR && n > 0) { if (send(fd, buf, n, 0) == SOCKET_ERROR) { fprintf(stderr, "echo send error: %d\n", WSAGetLastError()); } break; } n = recv(fd, buf, sizeof buf, 0); } if (n == SOCKET_ERROR) fprintf(stderr, "echo recv error: %d\n", WSAGetLastError()); closesocket(fd); 38 Advanced Windows Network Programming

Echo Server: Main Function Example int main(int argc, char **argv) { WSADATA wsadata; SOCKET listenfd, connfd; int clilen; struct sockaddr_in cliaddr, servaddr; if (WSAStartup(MAKEWORD(2,2), &wsadata)!= 0) errexit("wsastartup failed\n"); listenfd = socket(af_inet, SOCK_STREAM, 0); if (listenfd == INVALID_SOCKET) errexit("cannot create socket: error number %d\n", WSAGetLastError()); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(inaddr_any); servaddr.sin_port = htons(serv_port); if (bind(listenfd, (SA *) &servaddr, sizeof(servaddr)) == SOCKET_ERROR) errexit("can't bind to port %d: error number %d\n", SERV_PORT, WSAGetLastError()); if (listen(listenfd, 5) == SOCKET_ERROR) errexit("can't listen on port %d: error number %d\n", SERV_PORT, WSAGetLastError()); 39 Advanced Windows Network Programming

Echo Server: Main Function Example cont. } // cont. for ( ; ; ) { clilen = sizeof(cliaddr); connfd = accept(listenfd, (SA *) &cliaddr, &clilen); if (connfd == INVALID_SOCKET) errexit("accept failed: error number %d\n", WSAGetLastError()); // create a service thread to handle this client if (_beginthread((void (*)(void *))tcpechod, 0, (void *)connfd) < 0) errexit("_beginthread failed: error number %d\n", GetLastError()); } return 1; 40 Advanced Windows Network Programming

Echo Client: Sending Function Sample void str_cli(socket sockfd){ char sendline[maxline+1], recvline[maxline+1]; int cc, n_out, n_in; while (fgets(sendline, MAXLINE, stdin)!= NULL) { sendline[maxline] = '\0'; /* ensure line null-termination */ n_out = strlen(sendline); // send out the data of n_out bytes send(sockfd, sendline, n_out, 0); } // receive n_out bytes of data from server for (n_in = 0; n_in < n_out; n_in += cc) { cc = recv(sockfd, &recvline[n_in], n_out - n_in, 0); if (cc == SOCKET_ERROR) errexit("socket recv failed: %d\n", WSAGetLastError()); } recvline[n_in] = '\0 ; fputs(recvline, stdout); } closesocket(sockfd); 41 Advanced Windows Network Programming

Echo Client: Main Function Sample void main(int argc, char *argv[]){ SOCKET sockfd; struct sockaddr_in servaddr; WSADATA wsadata; if (WSAStartup(MAKEWORD(2,2), &wsadata)!= 0) errexit("wsastartup failed\n"); if (argc!= 2) errexit("usage: tcpechocli01 <IPaddress>"); sockfd = socket(af_inet, SOCK_STREAM, 0); if (sockfd == INVALID_SOCKET) errexit("cannot create socket: error number %d\n", WSAGetLastError()); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(serv_port); if ( (servaddr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE) errexit("inet_addr error: error number %d\n", WSAGetLastError()); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) errexit("connect error: error number %d\n", WSAGetLastError()); str_cli(sockfd); WSACleanup(); return 0; } 42 Advanced Windows Network Programming

References } Ch11, Douglas Comer, David Stevens, Internetworking With TCP/IP, Volume III } Chapter 28, Internet Essentials, Programming With Microsoft Visual C++ NET 6 th Ed. - George/ Kruglinski Shepherd. 2002 } Network Programming for Microsoft Windows, 2nd Ed. - Anthony Jones, Jim Ohlund. 2002. } Windows Sockets API Specification. } MSDN: Windows Socket 2 } The Winsock Programmer s FAQ } Beej's Guide to Network Programming } Introduction to Indy:http://www.swissdelphicenter.ch/en/showarticle.php?id=4 43 Advanced Windows Network Programming

Appendix TCP Client/Server Interaction 44 Advanced Windows Network Programming

Socket interface for Connectionless Iterative Server

TCP Client/Server Interaction /* Create socket for incoming connections */ if ((servsock = socket(pf_inet, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction echoservaddr.sin_family = AF_INET; /* Internet address family */ echoservaddr.sin_addr.s_addr = htonl(inaddr_any);/* Any incoming interface */ echoservaddr.sin_port = htons(echoservport); /* Local port */ if (bind(servsock, (struct sockaddr *) &echoservaddr, sizeof(echoservaddr)) < 0) DieWithError("bind() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction /* Mark the socket so it will listen for incoming connections */ if (listen(servsock, MAXPENDING) < 0) DieWithError("listen() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction for (;;) /* Run forever */ { clntlen = sizeof(echoclntaddr); if ((clntsock=accept(servsock,(struct sockaddr *)&echoclntaddr,&clntlen)) < 0) DieWithError("accept() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction Server is now blocked waiting for connection from a client Later, a client decides to talk to the server Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction /* Create a reliable, stream socket using TCP */ if ((sock = socket(pf_inet, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction echoservaddr.sin_family = AF_INET; /* Internet address family */ echoservaddr.sin_addr.s_addr = inet_addr(servip); /* Server IP address */ echoservaddr.sin_port = htons(echoservport); /* Server port */ if (connect(sock, (struct sockaddr *) &echoservaddr, sizeof(echoservaddr)) < 0) DieWithError("connect() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction if ((clntsock=accept(servsock,(struct sockaddr *)&echoclntaddr,&clntlen)) < 0) DieWithError("accept() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction echostringlen = strlen(echostring); /* Determine input length */ /* Send the string to the server */ if (send(sock, echostring, echostringlen, 0)!= echostringlen) DieWithError("send() sent a different number of bytes than expected"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction /* Receive message from client */ if ((recvmsgsize = recv(clntsocket, echobuffer, RCVBUFSIZE, 0)) < 0) DieWithError("recv() failed"); Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Client/Server Interaction close(sock); close(clntsocket) Client 1. Create a TCP socket 2. Establish connection 3. Communicate 4. Close the connection Server 1. Create a TCP socket 2. Bind socket to a port 3. Set socket to listen 4. Repeatedly: a. Accept new connection b. Communicate c. Close the connection

TCP Tidbits n Client must know the server s address and port n Server only needs to know its own port n No corsendrelation between send() and recv() Client ( Hello Bob ) recv() -> Hi Jane Server recv() -> Hello recv() -> Bob send( Hi ) send( Jane )

Closing a Connection n close() used to delimit communication n Analogous to EOF Echo Client send(string) while (not received entire string) recv(buffer) print(buffer) Echo Server recv(buffer) while(client has not closed connection) send(buffer) recv(buffer) close(socket) close(client socket)