Title: Network Programming
1Network Programming
2Sockets
- Machines can talk to each other regardless of
type - Provides a relatively simple API that will work
with many different protocols - Has become a standard for network programming
across platforms
3WinSock
- Derived from Berkeley Sockets (Unix)
- includes many enhancements for programming in the
windows environment - Open interface for network programming under
Microsoft Windows - API freely available
- Multiple vendors supply winsock
- Source and binary compatibility
- Collection of function calls that provide network
services
4gethostname()
- Get the name of the host the program is running
on. - int gethostname(char hostname, int bufferLength)
- Upon return hostname holds the name of the host
- bufferLength provides a limit on the number of
bytes that gethostname can write to hostname.
5Domain Name Library Routine(gethostbyname)
- gethostbyname() Given a host name (such as
acavax.lynchburg.edu) get host information. - struct hostent getbyhostname(char hostname)
- char h_name // official name of host
- char h_aliases // alias list
- short h_addrtype // address family (e.g.,
AF_INET) - short h_length // length of address (4 for
AF_INET) - char h_addr_list // list of addresses (null
pointer terminated)
6Internet Address Library Routines(inet_addr()
and inet_ntoa())
- unsigned long inet_addr(char address)
- converts address in dotted form to a 32-bit
numeric value in network byte order - (e.g., 128.173.41.41)
- char inet_ntoa(struct in_addr address)
- struct in_addr
- address.S_addr is the long int representation
7Internet Address Library Routines(gethostbyaddr)
- Get the name of the host the program is running
on. - struct hostent gethostbyaddr(char address, int
addressLength, int type) - address is in network byte order
- addressLength is 4 if type is AF_INET
- type is the address family (e.g., AF_INET)
8Differences Between Berkeley Sockets and WinSock
Berkeley WinSock bzero() memset() close() c
losesocket() read() not required
write() not required ioctl() ioctlsocket()
9Additional Features of WinSock 1.1
- WinSock supports three different modes
- Blocking mode
- socket functions dont return until their jobs
are done - same as Berkeley sockets
- Nonblocking mode
- Calls such as accept() dont block, but simply
return a status - Asynchronous mode
- Uses Windows messages
- FD_ACCEPT - connection pending
- FD_CONNECT - connection established
- etc.
10WinSock 2
- Supports protocol suites other than TCP/IP
- DecNet
- IPX/SPX
- OSI
- Supports network-protocol independent
applications - Backward compatible with WinSock 1.1
- Today it also means a more limited user-base
11WinSock 2 (Continued)
- Uses different files
- winsock2.h
- different DLL (WS2_-32.DLL)
- API changes
- accept() becomes WSAAccept()
- connect() becomes WSAConnect()
- inet_addr() becomes WSAAddressToString()
- etc.
12Basic Socket Calls(socket)
- // Berkeley form
- int socket(int family
- int type,
- int protocol)
- // WinSock form
- SOCKET socket (int family,
- int type,
- int protocol)
13socket (continued)
- SOCKET socket (int family,
- int type,
- int protocol)
- family is address family
- AF_INET // internet protocols
- AF_UNIX // unix internal protocols
- AF_NS // Xerox NS protocols
- AF_IMPLINK // Interface Message Processor
- type is
- SOCK_STREAM // stream socket
- SOCK_DGRAM // datagram socket
- SOCK_RAW // raw socket
- protocol is usually zero in applications
programming
14 main(int argc, char argv) const int
expectedArguments 1 if (argc !
expectedArguments1) cerr ltlt usage
ltlt argv0 ltlt ltserverNamegt ltlt endl
else cerr ltlt server name is ltlt
argv1 ltlt endl // The rest of the client
code goes here
15Basic Socket Calls(bind)
- // Berkeley form
- int bind(int sockfd
- struct sockaddr addr,
- int addrLen)
- // WinSock form
- int bind(SOCKET sockfd
- struct sockaddr addr,
- int addrLen)
16bind (continued)
- int bind (SOCKET sockfd,
- struct sockaddr addr,
- int addrLen)
- sockfd was returned from the socket() call
- addr is pointer to a sockaddr_in structure that
contains the server IP address and port number - struct sockaddr_in
- short sin_family // address family
- u_short sin_port // port number
- struct in_addr sin_addr //IP address (32-bits)
- addrLen - sizeof (struct sockaddr_in)
17Basic Socket Calls(listen)
- // Berkeley form
- int listen(int s
- int backlog)
- // WinSock form
- int listen (SOCKET s,
- int backlog)
18listen (continued)
- int listen (SOCKET s,
- int backlog)
- s was returned from the socket() call
- 1ltbackloglt5
- Backlog specifies the number of connection
requests that may be simultaneously waiting for
service. - This is NOT the number of clients that can be
receiving service simultaneously.
19Basic Socket Calls(accept)
- // Berkeley form
- int accept(int s
- struct sockaddr addr,
- int pointerToAddrLen)
- // WinSock form
- SOCKET accept (SOCKET s,
- struct sockaddr addr,
- int pointerToAddrLen)
20accept (continued)
- SOCKET accept (SOCKET s,
- struct sockaddr addr,
- int pointerToAddrLen)
- s was returned from the socket() call
- addr is pointer to a sockaddr structure that will
contain the client information - struct sockaddr
- unsigned short sa_family // Address Family
- AF_INET, AF_UNIX, AF_NS, AF_IMPLINK
- char sa_data14 // up to 14 bytes of
protocol-specific address - PointerToAddrLen can be set by accept
- The returned socket provides communication with
the client.
21Basic Socket Calls(connect)
- // Berkeley form
- int connect(int s
- struct sockaddr addr,
- int sizeOfAddr)
- // WinSock form
- int connect (SOCKET s,
- struct sockaddr addr,
- int sizeOfAddr)
22connect (continued)
- int connect (SOCKET s,
- struct sockaddr addr,
- int sizeOfAddr)
- s was returned from the socket() call
- addr is pointer to a sockaddr structure that will
contain the server information - struct sockaddr_in
- short sin_family // address family
- u_short sin_port // port number
- struct in_addr sin_addr //IP address (32-bits)
- sizeOfAddr is sizeOf(struct sockaddr)
23Basic Socket Calls(send)
- // Berkeley form
- int send(int s
- const char bytesToSend,
- int nBytes,
- int flags)
- // WinSock form
- int send (SOCKET s,
- const char bytesToSend,
- int nBytes,
- int flags)
24send (continued)
- int send (SOCKET s,
- const char bytesToSend,
- int nBytes,
- int flags)
- s was returned from the socket() call
- bytesToSend is a pointer to the data to send
- nBytes is the number of bytes to send
- flags
- e.g., MSG_OOB
- Note There is no guarantee that send will send
all the data requested. The number of bytes that
send actually transmits is returned as a the
result of the function. It may be necessary to
call send repeatedly in a loop to achieve the
desired result.
25send (continued)
- // Sample code that shows repeated calls to send
- int mustSend (SOCKET s,
- const char bytesToSend,
- int nBytes,
- int flags)
-
- int bytesSent 0
- while(bytesSent lt nBytes)
-
- bytesSent send(s, bytesToSendbytesSent,
nBytes-bytesSent, flags) -
- return(bytesSent)
-
26Basic Socket Calls(recv)
- // Berkeley form
- int recv(int s
- char bytesToReceive,
- int nBytes,
- int flags)
- // WinSock form
- int recv(SOCKET s,
- char bytesToReceive,
- int nBytes,
- int flags)
27recv (continued)
- int recv (SOCKET s,
- char bytesToReceive,
- int nBytes,
- int flags)
- s was returned from the socket() call
- bytesToReceive is a pointer to the data buffer
- nBytes is the maximum number of bytes to receive
- flags
- e.g., MSG_OOB
- Note There is no guarantee that recv will recv
all the data requested. The number of bytes that
recv actually received is returned by the
function. It may be necessary to call recv
repeatedly in a loop to achieve the desired
result.
28while( (_readPtr ! _delimiter)
(fieldCursor lt maxFieldLength-1) )
if (_charsInReadBuffer gt 0) // Is there data
to read? fieldfieldCursor
_readPtr // Copy read data
fieldCursor _readPtr
--_charsInReadBuffer // Do we
need to read more data? while
(_charsInReadBuffer 0)
_charsInReadBuffer recv(_socketfd, _readBuffer,
maxFieldLength, 0) _readPtr
_readBuffer
29Basic Socket Calls(write)
- // Berkeley form
- int write(int s
- const char bytesToSend,
- int nBytes)
- // WinSock form
- // Not necessarily supported
- // Uses Berkeley form when supported
30write (continued)
- int write (int s,
- char bytesToSend,
- int nBytes)
- s was returned from the socket() call
- bytesToSend is a pointer to the data to send
- nBytes is the number of bytes to send
- Note There is no guarantee that write will send
all the data requested. The number of bytes that
write actually transmits is returned as a the
result of the function. It may be necessary to
call write repeatedly in a loop to achieve the
desired result.
31Basic Socket Calls(read)
- // Berkeley form
- int read(int s
- char bytesToReceive,
- int nBytes)
- // WinSock form
- // Not necessarily supported
- // Uses Berkeley form when supported
32read (continued)
- int read(SOCKET s,
- char bytesToReceive,
- int nBytes)
- s was returned from the socket() call
- bytesToReceive is a pointer to the data buffer
- nBytes is the maximum number of bytes to receive
- Note There is no guarantee that read will read
all the data requested. The number of bytes that
read actually received is returned by the
function. It may be necessary to call read
repeatedly in a loop to achieve the desired
result.
33Basic Socket Calls(shutdown)
- // Berkeley form
- int shutdown(int s, int howto)
- // WinSock form
- int shutdown(Socket s, int howto)
34shutdown (continued)
- int shutdown(SOCKET s, int howto)
- s was returned from the socket() call
- howto
- SHUT_RD - shut down just the read direction. No
more reads or recvs can be issued on this socket.
However, writes and sends can still be used. - SHUT_WR - shutdown just the write direction. No
more writes and sends can be issued on this
socket. However, reads and recvs can still be
used. - SHUT_RDWR - this shuts down both directions. No
more data can be transmitted using the socket.
The socket still must be closed. - Note shutdown will terminate data transmission
regardless of the socket reference count (i.e.,
even if other threads havent yet closed the
socket.)
35Basic Socket Calls(close/closesocket)
- // Berkeley form
- int close(int s)
- // WinSock form
- int closesocket(Socket s)
36closesocket (continued)
- int closesocket(SOCKET s)
- s was returned from the socket() call
- Note There is no guarantee that read will read
all the data requested. The number of bytes that
read actually received is returned by the
function. It may be necessary to call read
repeatedly in a loop to achieve the desired
result.
37Basic Socket Calls(sendto)
- // Berkeley form
- int sendto(int s
- const char bytesToSend,
- int nBytes,
- int flags,
- struct sockaddr to,
- int sizeOfSockaddr)
- // WinSock form
- int sendto(SOCKET s,
- const char bytesToSend,
- int nBytes,
- int flags,
- struct sockaddr to,
- int sizeOfSockaddr)
38sendto (continued)
- int sendto (SOCKET s,
- const char bytesToSend,
- int nBytes,
- int flags
- struct sockaddr to,
- int sizeOfSockaddr)
- to is a struct sockaddr_in
- struct sockaddr_in
- short sin_family // address family
- u_short sin_port // port number
- struct in_addr sin_addr //IP address (32-bits)
- sizeOfSockaddr is sizeof(struct sockaddr_in)
- Note Although this function can be used with
TCP connected sockets it is really designed for
use with UDP connectionless sockets. There is no
guarantee that data sent with a successful send
will arrive at its destination.
39Basic Socket Calls(recvfrom)
- // Berkeley form
- int recvfrom(int s
- char receivedData,
- int nBytes,
- int flags,
- struct sockaddr from,
- int sizeOfSockaddr)
- // WinSock form
- int recvfrom(SOCKET s,
- char receivedBytes,
- int nBytes,
- int flags,
- struct sockaddr from,
- int sizeOfSockaddr)
40recvfrom (continued)
- int recvfrom (SOCKET s,
- char receivedData,
- int nBytes,
- int flags
- struct sockaddr from,
- int sizeOfSockaddr)
- to is a struct sockaddr_in
- struct sockaddr_in
- short sin_family // address family
- u_short sin_port // port number
- struct in_addr sin_addr //IP address (32-bits)
- sizeOfSockaddr is sizeof(struct sockaddr_in)
- Note Although this function can be used with
TCP connected sockets it is really designed for
use with UDP connectionless sockets. There is no
guarantee that data sent with a successful send
will arrive at its destination.
41Basic System Calls(fork)
- // Berkeley form
- int fork()
- // WinSock form
- // not necessarily available under windows
42fork (continued)
- int fork()
- Fork creates a new process
- Typically the new process handles a client
request while the original process continues
waiting for new clients.
43 for( ) / Wait for a connection. /
clilen sizeof(cli_addr) newsockfd
accept(sockfd, (struct sockaddr ) cli_addr,
clilen) if (newsockfd lt 0)
cerr ltlt accept failed, errno ltlt errno ltlt
endl else // Create a new
process to process the request int pid
0 pid fork() // The child
process handles the request if (pid ! 0)
processServerRequest(newsockfd)