Você está na página 1de 19

Systems Programming

Introduction to the

Sockets API

TCP/IP Protocol Family

Image from http://www.tcpipguide.com

TCP/IP Protocol Family Image from http://www.tcpipguide.com Systems Programming Richard Anthony, Computer Science, The University of Greenwich

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Developing Networked Applications Overview of basic concepts

1. The TCP/IP family of protocols includes the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP) in the Transport Layer. Applications that directly transmit data over the network use either, or both, of these.

  • 2. TCP and UDP both operate over the Internet Protocol (IP), which works in

the Network Layer.

  • 3. IP will deliver a Packet to a destination computer but does not know

about processes.

  • 4. TCP and UDP are process-to-process communication. Ports are used to

identify a particular process within a computer. The combination of IP address and port number is a unique identifier of

a particular process in a network. (combination IP address and and identify specific destination)

  • 5. To use the TCP or UDP protocols, an application developer uses the

‘sockets API’ to make calls to the protocol software stack.

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Developing Networked Applications TCP and UDP key facts in brief

1. TCP is a far more complex protocol than UDP. - TCP supports flow control, congestion control, sequence numbers and automatic retransmission if a segment is lost, to ensure reliability. - UDP is a minimal protocol, and not reliable.

2. TCP forms Virtual Connections, which means that before data can be sent a connection must be set up, and after data transmission is complete, the connection must be removed. UDP is Connectionless, it enables immediate sending of data without any additional handshaking.

3. TCP communication is always one-one. UDP communication can be one-one, or broadcast (one to all).

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API Overview (at the endpoints)

The sockets Application Programmer Interface (API) is an interface that a programmer uses to configure and use the TCP and UDP communication

protocols from within an application.

The central concept is that ‘sockets’ within each communicating process are

connected together.

TCP and UDP work in the Transport layer, thus this is a ‘Virtual’ socket, i.e. it is a structure in memory that represents the endpoint for communication, it is NOT a physical socket.

Virtual Sockets

Communication endpoints for transport-layer process-process

communication

Physical Sockets

(e.g. where you plug

an Ethernet cable). Nothing to do with TCP or UDP

Computer 1

Process 1

Process 2

Computer 2 Process 3 Process 4
Computer 2
Process 3
Process 4
Sockets API – Overview (at the endpoints) The sockets Application Programmer Interface (API) is an interface

55

Sockets API – Overview (at the endpoints) The sockets Application Programmer Interface (API) is an interface

Network

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API UDP Primitives sequence

1. The socket primitive is used to create a socket.

  • 2. The bind primitive is used to map a process to a port.

  • 3. The sendto primitive is used to send data to another process.

  • 4. The recvfrom primitive is used to retreive data from the receive buffer.

  • 5. The closesocket primitive is used to close the socket.

A typical exchange could be:

Process1 socket bind recvfrom closesocket

Process2 socket bind sendto closesocket

sendto

recvfrom

Sockets API – UDP Primitives sequence 1. The socket primitive is used to create a socket.

recvfrom

sendto

sendto

recvfrom

Sockets API – UDP Primitives sequence 1. The socket primitive is used to create a socket.

Ti

Systems Programming

66

Richard Anthony, Computer Science, The University of Greenwich

Sockets API TCP Primitives sequence

1. The socket primitive is used to create a socket.

  • 2. The bind primitive is used to map a process to a port.

  • 3. The listen, connect and accept primitives are used to set up a connection.

  • 4. The send primitive is used to send data to another process.

  • 5. The recv primitive is used to retrieve data from the receive buffer.

  • 6. The shutdown primitive is used to close the connection.

  • 7. The closesocket primitive is used to close the socket.

A typical exchange could be:

Process1

socket

bind

listen

accept send

recv

listen accept send recv
listen accept send recv

(server)

Process2 (client) socket connect

recv

send

Sockets API – TCP Primitives sequence 1. The socket primitive is used to create a socket.

Process1

send recv
send
recv

shutdown closesocket

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

77

Sockets API - 1

socket() - create a new socket, identified by an integer number. Used with TCP and UDP.

Prototype:

SOCKET socket( int AddressFamily, int Type, int Protocol)

Types: SOCK_DGRAM (for UDP), SOCK_STREAM (for TCP)

Return parameter SOCKET is derived from an integer type and identifies the socket

Example:

SOCKET m_ReceiveSOCKET;

m_ReceiveSOCKET = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); if(INVALID_SOCKET == m_ReceiveSOCKET) {

MessageBox("Could not create socket","Simple Receive Dialog");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 2

bind() - associates a socket with an address (a local port and IP address). The side that will be connected-to, i.e. the server-side must issue this call,

so that clients can ‘locate’ the server by its port number.

Prototype:

int bind( SOCKET s, const struct sockaddr* name, int namelen );

If no error occurs, bind returns zero. Otherwise, it returns an error code

struct sockaddr this is a special structure that holds the address to bind to (i.e. includes IP address and port number)

Example:

int iError = bind(m_ReceiveSOCKET, (const SOCKADDR FAR*)&m_LocalSockAddr,

sizeof(m_LocalSockAddr)); if(SOCKET_ERROR == iError) {

MessageBox("bind() Failed!","Simple Receive Dialog");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 3

listen() is used on the server side, after ‘bind’. This sets the socket into listening-for-connection state. This is only used with TCP sockets.

Prototype:

int listen( SOCKET s, int backlog );

If no error occurs, listen returns zero. Otherwise, it returns an error code

backlog is the maximum length of the queue of pending connections.

Example:

iResult = listen(m_iSocket, 5); if(SOCKET_ERROR == iResult) {

MessageBox("Listen failed");

}

exit(1);

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 4

connect() is used on the client side, to establish a new TCP connection with another process. This is only needed with TCP sockets.

Prototype:

int connect( SOCKET s, const struct sockaddr* name,

int namelen ); If no error occurs, connect returns zero. Otherwise, it returns an error code

namelen is the size of the sockaddr structure

Example:

iError = connect(m_iSocket, (const SOCKADDR FAR*)&m_ConnectSockAddr, sizeof(m_ConnectSockAddr));

if(SOCKET_ERROR == iError) {

MessageBox("Connect failed","Client");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 5

accept() is used on the server side. It allows a connection request from a client to be fulfilled (i.e. accepted). accept automatically creates a new socket for the server side to use with this connection. This is only needed with TCP sockets.

Prototype:

SOCKET accept( SOCKET s, struct sockaddr* addr,

int* addrlen ); If no error occurs, accept returns a valid socket.

addrlen is the size of the sockaddr structure

Example:

m_ConnectSocket = accept(m_iSocket, (SOCKADDR FAR*)& m_ConnectSockAddr, &iRemoteAddrLen); if(INVALID_SOCKET == m_ConnectSocket ) {

MessageBox("Accept failed","Server");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 6

send() is used to send data, over a TCP connection.

Prototype:

int send( SOCKET s, const char* buf, int len, int flags );

If no error occurs, send returns the number of bytes sent. Otherwise, it returns

an error code.

buf is the area of memory containing the message to send len is the size of the message in the buffer flags can be used to specify some control options

Example:

int iBytesSent; iBytesSent = send(m_ConnectSocket , (char *) &Message, sizeof(Message_PDU), 0); if(SOCKET_ERROR == iBytesSent) {

MessageBox("Failed to send","Server");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 7

recv() is used to check the local buffer to see if any messages have been received and placed there (used with a TCP connection). If there is a message in the buffer, recv passes it to the application.

Prototype:

int recv( SOCKET s, char* buf, int len, int flags );

If no error occurs, recv returns the number of bytes received. If the connection

has been closed, the return value is zero. Otherwise, it returns an error code.

buf is the area of memory that will contain the message len is the size of the buffer (i.e. the maximum amount of data that can be retrieved in one go). flags can be used to specify some control options

Example:

int iBytesRecd; iBytesRecd = recv(m_iSocket, (char *) &Message, sizeof(Message_PDU), 0); if(SOCKET_ERROR == iBytesRecd) {

MessageBox("Receive failed","Client");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 8

sendto() is used to send data, over UDP.

Prototype:

int sendto( SOCKET s, const char* buf, int len, int flags,

const struct sockaddr* to, int tolen ); If no error occurs, sendto returns the number of bytes sent. Otherwise, it returns an error code.

buf is the area of memory containing the message to send len is the size of the message in the buffer flags can be used to specify some control options to is the sockaddr structure holding the address, tolen is the size of the address structure

Example:

int iBytesSent = sendto(m_SendSOCKET, (char FAR *)m_szSendBuf, m_iSendLen, 0, (const struct sockaddr FAR *)&m_SendSockAddr, sizeof(m_SendSockAddr)); if(INVALID_SOCKET == iBytesSent) {

MessageBox("sendto() Failed!","Simple Send Dialog");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 9

recvfrom() is used to check the local buffer to see if any messages have been received and placed there (used with UDP). If there is a message in the buffer, recvfrom passes it to the application.

Prototype:

int recvfrom( SOCKET s, char* buf, int len, int flags, struct

sockaddr* from, int* fromlen ); If no error occurs, recvfrom returns the number of bytes received. If the connection has been closed, the return value is zero. Otherwise, it returns an error code.

buf is the area of memory that will contain the message len is buffer size (i.e. max amount of data that can be retrieved in one go) flags can be used to specify some control options from is a sockaddr structure containing the sender’s address (optional) fromlen is the length of the address structure

Example:

int iBytesRecd = recvfrom(m_ReceiveSOCKET, (char FAR*)m_szRecvBuf, RECEIVE_BUFFER_SIZE, 0, NULL, NULL); if(SOCKET_ERROR == iBytesRecd) MessageBox(“No message in the buffer","Simple Receive Dialog");

{

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 10

setsockopt() is used to set options concerning the way sockets are used. For example to enable UDP to operate in Broadcast mode.(broadcast:send to all computer)

Prototype:

int setsockopt( SOCKET s, int level, int optname,

const char* optval, int optlen ); If no error occurs, setsockopt returns zero. Otherwise, it returns an error code

level is the level at which the option applies (usually SOL_SOCKET ) optname is the name of the option to set optval is the value to set the option to optlen is the length of the value data

Example:

char cOpt[2];

cOpt[0] = 1; // true cOpt[1] = 0; // null terminate the option array int iError = setsockopt(m_SendSOCKET, SOL_SOCKET, SO_BROADCAST, cOpt, sizeof(cOpt));

if(SOCKET_ERROR == iError) { MessageBox("setsockopt() Failed!","Simple Send Dialog"); }

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 11

shutdown() close the connection. Used with TCP.

Prototype:

int shutdown( SOCKET s, int how );

If no error occurs, shutdown returns zero. Otherwise, it returns an error code.

how is a flag which indicates what actions will no longer be allowed SD_RECEIVE, subsequent calls to recv are disallowed. SD_SEND, subsequent calls to send are disallowed. SD_BOTH disables both sends and receives.

Example:

int iError = shutdown(m_ConnectSocket, SD_BOTH ); if(SOCKET_ERROR == iError) {

MessageBox("shutdown() Failed!","Send Dialog");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich

Sockets API - 12

closesocket() close the socket. Used with TCP and UDP.

Prototype:

int closesocket( SOCKET s );

If no error occurs, closesocket returns zero. Otherwise, it returns an error code.

Example:

int iError = closesocket(m_ConnectSocket); if(SOCKET_ERROR == iError) {

MessageBox(" closesocket() Failed!","Send Dialog");

}

Systems Programming

Richard Anthony, Computer Science, The University of Greenwich