04 - socket programming

Upload: jameskachirosarumaha

Post on 07-Apr-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/4/2019 04 - Socket Programming

    1/12

    CS4233 Network Programming

    Socket Programming

    Chen-Lung Chan

    Department of Computer Science

    National Tsing Hua University

    Socket Interface

    UNIX domain socket Local IPC AF_UNIX

    Filesystem: path name

    Internet domain socket

    Internet communications AF_INET

    Internet address: IP + Port

    A Client-Server Exchange

    Clientprocess

    Serverprocess

    1. Client sends request

    2. Server

    handlesrequest

    3. Server sends response4. Client

    handlesresponse

    Resource

    A serverprocess and one or more clientprocesses

    Server manages some resource. Server provides serviceby manipulating

    resource for clients.

    Network Applications

    OS

    NetworkInterface

    ClientAppl.

    SocketOS +NetworkAPIs

    OS

    NetworkInterface

    ServerAppl.

    SocketOS +NetworkAPIs

    Internet

    Client MachineClient Machine Server MachineServer Machine

    Access to Network via Program Interface Sockets make network I/O look like files Call system functions to control and communicate Network code handles issues of routing, segmentation.

  • 8/4/2019 04 - Socket Programming

    2/12

    Internet Connections (TCP/IP)

    Connection socket pair(140.114.78.11:3479, 140.114.78.20:80)

    Server(port 80)

    Client

    Client socket address140.114.78.11:3479

    Server socket address140.114.78.20:80

    Client host address140.114.78.11

    Server host address140.114.78.20

    Note:3479is an portrandomlyallocatedby the kernel

    Note:80is awell-knownportassociated with Web servers

    Two common paradigms for clients and servers communication Datagrams (UDP protocol, SOCK_DGRAM)

    Connections (TCP protocol, SOCK_STREAM)

    Connections are point-to-point, full-duplex (2-waycommunication), and reliable. (TODAYS TOPIC!)

    Clients

    Examples of client programs

    Web browsers, ftp, telnet, ssh How does a client find the server?

    The IP address in the server socket address identifies thehost (more precisely, an adaptor on the host)

    The (well-known) port in the server socket address identifiesthe service, and thus implicitly identifies the server processthat performs that service.

    Examples of well known ports Port 7: Echo server

    Port 23: Telnet server Port 25: Mail server

    Port 80: Web server

    Using Ports to Identify Services

    Web server(port 80)

    Client host

    Server host 140.114.78.20

    Echo server(port 7)

    Service request for140.114.78.20:80

    (i.e., the Web server)

    KernelClient

    Web server(port 80)

    Echo server(port 7)

    Service request for140.114.78.20:7

    (i.e., the echo server)KernelClient

    Servers

    See /etc/services for a

    comprehensive list of theservices available on aLinux machine.

    Servers are long-running processes (daemons). Created at boot-time (typically) by the init process (process 1)

    Run continuously until the machine is turned off.

    Each server waits for requests to arrive on a well-known port associated with a particular service. Port 7: echo server

    Port 23: telnet server

    Port 25: mail server

    Port 80: HTTP server

    A machine that runs a server process is also often

    referred to as a server.

  • 8/4/2019 04 - Socket Programming

    3/12

    Using netstat

    The netstatcommand prints a lot of

    useful network information such asnetwork connections, routing tables, andinterface statistics. netstat: display a list of open sockets

    netstata: show both listening and non-listening sockets

    Using netstatto view the status of yoursocket program!

    Sockets

    What is a socket?

    To the kernel, a socket is an endpoint ofcommunication. To an application, a socket is a file descriptor that

    lets the application read/write from/to the network. Remember: All Unix I/O devices, including networks, are

    modeled as files.

    Clients and servers communicate with each byreading from and writing to socket descriptors.

    The main distinction between regular file I/Oand socket I/O is how the application opensthe socket descriptors.

    Overview of the SocketsInterface

    Client /ServerSession

    Client Server

    socket socket

    bind

    listen

    read

    writeread

    write

    Connectionrequest

    read

    close

    close EOF

    Await connectionrequest fromnext client

    open_listenfd

    open_clientfd

    acceptconnect

    struct sockaddr_in serveraddr;

    /* fill in serveraddr with an address */

    /* Connect takes (struct sockaddr *) as its second argument */

    connect(clientfd, (struct sockaddr *) &serveraddr,sizeof(serveraddr));

    Network Byte Ordering Network is big-endian, host may be big- or little-endian Functions work on 16-bit (short) and 32-bit (long) values htons()/htonl(): convert host byte order to network byte order ntohs()/ntohl(): convert network byte order to host byte order Use these to convert network addresses, ports,

    Structure Casts You will see a lot of structure casts

    Socket Programming Cliches

  • 8/4/2019 04 - Socket Programming

    4/12

  • 8/4/2019 04 - Socket Programming

    5/12

    Echo Client: socket()

    int clientfd; /* socket descriptor */

    if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

    return -1; /* check errno for cause of error */

    ... (more)

    socket() creates a socket descriptor on the

    client. AF_INET: indicates that the socket is associated

    with Internet protocols. SOCK_STREAM: selects a reliable byte stream

    connection.

    Echo Client: gethostbyname()

    The client then builds the servers Internet address.

    int clientfd; /* socket descriptor */

    struct hostent *hp; /* DNS host entry */

    struct sockaddr_in serveraddr; /* servers IP address */

    ...

    /* fill in the server's IP address and port */

    if ((hp = gethostbyname(hostname)) == NULL)

    return -2; /* check h_errno for cause of error */

    bzero((char *) &serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    bcopy((char *)hp->h_addr,(char *)&serveraddr.sin_addr.s_addr, hp->h_length);

    serveraddr.sin_port = htons(port);

    Echo Client: connect()

    Finally, the client creates a connection with the server. Client process suspends (blocks) until the connection is

    created.

    After resuming, the client is ready to begin exchangingmessages with the server via Unix I/O calls on descriptorsockfd.

    int clientfd; /* socket descriptor */

    struct sockaddr_in serveraddr; /* server address */

    ...

    /* Establish a connection with the server */

    if (connect(clientfd, (struct sockaddr *)&serveraddr,

    sizeof(serveraddr)) < 0)

    return -1;

    Echo Client: read() & write()

    After the connection is established, we canuse read() and write() to exchange data

    between the client and the server. The use of read() and write() are the same as we

    mentioned in Direct File I/O.

    However, recv() and send() are suggested dueto their compatibility with Winsock. #include

    ssize_t recv(int s, void *buf, size_t len, int flags)

    ssize_t send(int s, const void *buf, size_t len, intflags)

  • 8/4/2019 04 - Socket Programming

    6/12

    Servers and Sockets

    client 1 server client 2

    call connect call accept

    ret connectret accept

    call connect

    call readwrite

    ret readclose

    close call accept

    ret connect

    call read

    ret read

    close

    write

    ret accept

    close

    Server must be able to handle multiple requests

    Where should pending connections be queued up?

    Echo Server (1/2)

    Create a socket

    socket() Announce the service

    bind()

    Wait for connection listen()

    accept()

    Exchange data read(), write()

    recv(), send() Close the socket

    close()

    Echo Server (2/2)

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

    return -1;

    /* Listenfd will be an endpoint for all requests to porton any IP address for this host */

    bzero((char *) &serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    serveraddr.sin_port = htons((unsigned short)port);

    if (bind(listenfd, (struct sockaddr *)&serveraddr,

    sizeof(serveraddr)) < 0)

    return -1;

    /* Make it a listening socket ready to accept connection requests */

    if (listen(listenfd, LISTENQ) < 0)

    return -1;

    Echo Server: Initialize SocketAddress

    struct sockaddr_in serveraddr; /* server's socket addr */

    bzero((char *) &serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    serveraddr.sin_port = htons((unsigned short)port);

    IP addresses INADDR_ANY: address to accept any incoming messages INADDR_LOOPBACK: 127.0.0.1 (local host) The server is only active on the specified IP address

    Ex: public IP: 140.114.78.20, but the program bind at 127.0.0.1

    only the clients in the local host can contact the server

    IP addr and port stored in network (big-endian) byte order

    htonl() converts longs from host byte order to network byte order. htons() converts shorts from host byte order to network byte order.

  • 8/4/2019 04 - Socket Programming

    7/12

    Echo Server: bind() & listen()

    bind() associates the socket with the socket addresswe just created.

    listen() indicates that this socket will accept connection(connect()) requests from clients.

    bzero((char *) &serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    serveraddr.sin_port = htons((unsigned short)port);

    if (bind(listenfd, (struct sockaddr *)&serveraddr,

    sizeof(serveraddr)) < 0)

    return -1;if (listen(listenfd, LISTENQ) < 0)

    return -1;

    Echo Server: accept()

    listenfd(3)

    Client

    1. Server blocks in accept(),

    waiting for connection requeston listening descriptor listenfd.clientfd

    Server

    listenfd(3)

    Client

    clientfd

    Server2. Client makes connectionrequest by calling and blockingin connect().

    Connectionrequest

    listenfd(3)

    Client

    clientfd

    Server

    3. Server returns connfd from

    accept(). Client returns fromconnect(). Connection is nowestablished between clientfd andconnfd.

    connfd(4)

    Echo Server: Main Loop

    The server loops endlessly, waiting for connectionrequests, then reading input from the client, andechoing the input back to the client.

    main() {

    /* create and configure the listening socket */

    while(1) {

    /* accept(): wait for a connection request */

    /* echo(): read and echo input lines from client til EOF */

    /* close(): close the connection */

    }

    }

    Echo Server: accept()

    int listenfd; /* listening descriptor */

    int connfd; /* connected descriptor */

    struct sockaddr_in clientaddr;int clientlen;

    clientlen = sizeof(clientaddr);

    connfd = accept(listenfd, (struct sockaddr_in *)&clientaddr,

    &clientlen);

    accept() blocks waiting for a connection request.

    accept() returns a connected descriptor(connfd) with the sameproperties as the listening descriptor(listenfd) Returns when the connection between client and server is created

    and ready for I/O transfers. All I/O with the client will be done via the connected socket.

    accept() also fills in clients IP address.

  • 8/4/2019 04 - Socket Programming

    8/12

    Summary of Socket APIs

    int socket(int domain, int type, int protocol);

    int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t

    addrlen); int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

    int listen(int s, int backlog);

    int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

    ssize_t read(int fd, void *buf, size_t count);

    ssize_t write(int fd, const void *buf, size_t count);

    ssize_t recv(int s, void *buf, size_t len, int flags);

    ssize_t send(int s, const void *buf, size_t len, int flags); int shutdown(int s, int how);

    int close(int fd);

    uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);

    Other Socket APIs - Address

    Internet address manipulation struct hostent *gethostbyname(const char *name)

    returns a structure of type hostentfor the given host name in_addr_t inet_addr(const char *cp)

    convert the Internet host address cp from numbers-and-dots notationinto binary data in network byte order

    char *inet_ntoa(struct in_addr in) convert the Internet host address in given in network byte order to a

    string in standard numbers-and-dots notation (a.b.c.d) The string is returned in a statically allocated buffer, which subsequent

    calls will overwrite.

    Socket name int getsockname(int s, struct sockaddr *name, socklen_t *namelen)

    get socket name int getpeername(int s, struct sockaddr *name, socklen_t *namelen)

    get name of connected peer socket

    Other Socket APIs - Socket Options

    int setsockopt(SOCKET s, int level, intoptname, const char FAR* optval, int optlen)

    int getsockopt(SOCKET s, int level, intoptname, char FAR* optval, int FAR* optlen)

    Useful options level = SOL_SOCKET

    SO_RCVBUF

    SO_SNDBUF

    level = IPPROTO_TCP

    TCP_NODELAY

    Some Helpful Tools

    ps The pscommand reports process status program.

    telnet The telnetcommand can be used as a client

    program for testing. Ex: telnet cs22.cs.nthu.edu.tw 21

    Then, we can communicate directly with the FTP server.

    netstat The netstatcommand prints a lot of useful network

    information such as network connections, routingtables, and interface statistics. Ex: we can see the actual address that our program binds.

  • 8/4/2019 04 - Socket Programming

    9/12

    Problem: Close Socket

    int sock = socket(AF_INET, SOCK_STREAM, 0);bind(sock, (struct sockaddr *)&name, sizeof(struct sockaddr_in));

    listen(sock, 5);int ns = accept(sock, NULL, NULL);char buf[1024] = "Test!!\r\n";send(ns, buf, strlen(buf), 0);close(ns);close(sock);

    When you re-execute the above code, you may get an error ofBind: Address Already in Use .

    This is because the socket is not released immediately. $ netstat -a

    cs22.4233 cs22.50414 5840 0 10136 0 TIME_WAIT

    Bind: Address Already in Use (1/2)

    LAST_ACK

    Local end initiates closure Remote end initiates closure

    Closing first guaranteesTIME_WAIT

    States of a server socket

    receive ACK

    close() is called,send FIN

    Closing second avoidsTIME_WAIT

    CLOSED

    TIME_WAIT

    FIN_WAIT_2 CLOSING

    FIN_WAIT_1

    close() is called,send FIN

    receive ACK receive FINand send ACK

    receive FINand send ACK

    receive ACK

    timeout completes

    CLOSE_WAIT

    ESTABLISHED

    receive FINand send ACK

    Bind: Address Already in Use (2/2)

    It is possible for the process to completebefore the kernel has released the associatednetwork resource, and this port cannot bebound to another process until the kernel hasdecided that it is done.

    Avoidance SO_REUSEADDR

    Use setsockopt() to set the SO_REUSEADDR socketoption, which explicitly allows a process to bind to a portwhich remains in TIME_WAIT

    Client closes first

    Reduce timeout Shorten the timeout associated with TIME_WAIT

    Design a Protocol (1/2)

    Avoid passing binary data 32 bit vs 64 bit

    Byte order Little endian vs big endian

    Ex: FTP telnet cs22.cs.nthu.edu.tw 21

    220-

    220-=====================================================

    220- Department of Computer Science

    220- National Tsing Hua University

    220-

    220- Host: cs22.cs.nthu.edu.tw [140.114.87.72]

    220------------------------------------------------------

    220- Connected from: vc.cs.nthu.edu.tw [140.114.78.20]

    220 cs22 FTP server (Version 4.122 Fri Feb 5 17:14:49 CST 1999) ready.

  • 8/4/2019 04 - Socket Programming

    10/12

    Design a Protocol (2/2)

    Ex: FTP contd

    HELP

    214- The following commands are recognized (* =>'s unimplemented).

    USER PORT STOR MSAM* RNTO NLST MKD CDUP

    PASS PASV APPE MRSQ* ABOR SITE XMKD XCUP

    ACCT* TYPE MLFL* MRCP* DELE SYST RMD STOU

    SMNT* STRU MAIL* ALLO CWD STAT XRMD SIZE

    REIN* MODE MSND* REST* XCWD HELP PWD MDTM

    QUIT RETR MSOM* RNFR LIST NOOP XPWD

    USER xxxxxxxx

    331 Password required for xxxxxxxx.

    commands

    return code

    FTP Protocol

    Client Server

    accept()

    connect()

    220 Welcome Message

    USER xxxx

    331 Password required for xxxx.

    PORT a,b,c,d,e,f

    200 PORT command successful.

    RETR filename

    bind() & listen() connect()

    accept()

    bind() & listen()

    QUIT

    Hint: CRLF = \r\nPASS yyyy

    230 User xxxx logged in.

    Notes of TCP Socket (1/3)

    The result of recv() on a TCP socket may notbe the same as your prediction.

    Ex1: A sends This is a test!!\r\n to B In A: send(sA, This is a test!!\r\n, 18, 0);

    In B: recv(sB, buf, sizeof(buf), 0);

    What is the result of buf? It may be

    This is a test!!\r\n

    This is a

    This

    Notes of TCP Socket (2/3)

    Ex2: A sends This is a test!!\r\n and Testagain!!\r\n to B

    In A: send(sA, This is a test!!\r\n, 18, 0);send(sA, Test again!!\r\n, 14, 0);

    In B: recv(sB, buf, sizeof(buf), 0);

    What is the result of buf? It may be

    This is a test!!\r\n

    This is a test!!\r\nTest again!!\r\n

    This is a

    This is a test!!\r\nTest

  • 8/4/2019 04 - Socket Programming

    11/12

    Notes of TCP Socket (3/3)

    The return value of recv(), i.e., the length,

    is unpredictable. Ensure that the message has been

    completely received before parsing it.

    What should we do?

    Append the received data into a buffer Repeat the above step until \r\n is received

    Parsing the Message (1/2)

    String operations strcmp() strtok() strstr() sprintf()

    The above functions only deal with strings, i.e., acharacter array which ends with \0. Ex: char buf[5] = test;

    buf[0] = t; buf[1] = e; buf[2] = s; buf[3] = t; buf[4] = \0;

    So, if you receive 10 bytes from the socket and storethem into char buf[20], remember to set buf[10] as\0 before you use the above string functions. Hint: always let the content of the buffer be a string

    Parsing the Message (2/2)

    char buf[256]

    256

    int count = recv(sock, buf, sizeof(buf), 0);T e s

    T e s \0

    buf[count] = \0;

    char *p = strstr(buf, \r\n);

    t \r \n T int len = recv(sock, buf+count, sizeof(buf)-count, 0);

    t \r \n T

    buf[count+len] = \0;

    \0

    p = strstr(buf, \r\n);

    // get the message from the buffer

    memcpy();

    Stabilize Your Program

    Message parsing Be careful to use string operations

    Check return values The socket APIs would return errors bind(), accept(), connect(), recv(), send()

    Remember to release unnecessary resources Close the sockets once you do not require them

    anymore

    Thread synchronization/interprocesscommunications Be careful to design the system flow.

  • 8/4/2019 04 - Socket Programming

    12/12

    What is Peer-to-Peer (P2P)?

    Peer-to-peer is a way of structuring

    distributed applications such that theindividual nodes have symmetric roles.

    Rather than being divided into clientsand servers each with quite distinct roles,in P2P applications a node may act as

    both a client and a server.

    Client-Server vs. P2P

    Client-server

    Clients are dumb little is assumed Servers do most things (compute, store, control)

    Centralization makes things simple

    But introduces

    Single point of failure/bottleneck, tighter control,

    P2P

    Peers (typically) have equal functionality A peer can be a client, a server, or a router