Title: Socket Programming
1Socket Programming
- CS 204 Advanced Programming
- Erkay Savas
- Expanded by Berrin Yanikoglu (2nd half)
2Overview of Network Protocols
- The Internet is a collection of networks,
including local networks at a number of
University and research institutions, and a
number of military networks. The term "Internet"
applies to this entire set of networks. - All of these networks are connected to each
other. Users can send messages from any of them
to any other, except where there are security or
other policy restrictions on access. - The "Internet protocol suite is a set of
protocols developed to allow cooperating
computers to communicate and share resources
across a network. - TCP and IP are two protocols in this suite.
3Overview of Network Protocols
- IP, TCP, and UDP provide "low- level" functions
needed for many applications. Other protocols are
for specific tasks, e.g. transferring files
between computers (FTP), sending mail (SMTP)
4ftp server
telnet server
web server
5A TCP/IP Network
application
TCP
IP
(e.g. Ethernet)
Router
6Communication Protocols
Application protocol
Web client
Web server
HTTP
7- The application protocols run "on top" of
TCP/IP. - They open a connection to a specified computer,
log into it, tell it what file you want, and
control the transmission of the file. - When they want to send a message, they give the
message to TCP. - Because TCP and IP take care of all the
networking details, the applications protocols
can treat a network connection as if it were a
simple byte stream, like a terminal or phone
line.
8Internet Protocol Suite
- Application protocol such as HTTP, FTP
- TCP (the "transmission control protocol")
responsible for breaking up the message into
datagrams, reassembling them at the other end,
resending what gets lost, and putting things back
in the right order. - Information is transfered as a sequence of
"datagrams (a collection of data sent as a
single message) that are sent through the network
individually. Datagrams can come in any order and
are reordered at the receiving end. - TCP puts a header at the front of each datagram.
This header actually contains at least 20 octets,
but the most important ones are a source and
destination "port number, a "sequence number
and a checksum. The port numbers are used to
keep track of different conversations. Suppose 3
different people are transferring files. Your TCP
might allocate port numbers 1000, 1001, and 1002
to these transfers. - IP (the "internet protocol") responsible for
routing individual datagrams, often over several
networks. - Find a route for the datagram and get it to the
other end. - In order to allow gateways or other intermediate
systems to forward the datagram, it adds its own
header. The main things in this header are the
source and destination Internet address (32-bit
addresses, like 128.6.4.194), the protocol
number, and another checksum.
9Internet Protocol Suite
- Ethernet is a "broadcast medium".
- When you send a packet out on the Ethernet, every
machine on the network sees the packet. So
something is needed to make sure that the right
machine gets it. As you might guess, this
involves the Ethernet header. - Every Ethernet packet has a 14-octet header that
includes the source and destination Ethernet
address, and a type code. Each machine is
supposed to pay attention only to packets with
its own Ethernet address in the destination
field. - Note that there is no connection between the
Ethernet address and the Internet address. - When these packets are received by the other end,
all the headers are removed. - The Ethernet interface removes the Ethernet
header and the checksum. It looks at the type
code. Since the type code is the one assigned to
IP, the Ethernet device driver passes the
datagram up to IP. - IP removes the IP header. It looks at the IP
protocol field. Since the protocol type is TCP,
it passes the datagram up to TCP. - TCP now looks at the sequence number. It uses the
sequence numbers and other information to combine
all the datagrams into the original file.
10Application Layer
- Suppose you want to send a file to a computer
whose Internet address is 128.6.4.7. To start the
process, you need more than just the Internet
address. You have to connect to the FTP server at
the other end. - In general, network programs are specialized for
a specific set of tasks. Most systems have
separate programs to handle file transfers,
remote terminal logins, mail, etc. - When you connect to 128.6.4.7, you have to
specify that you want to talk to the FTP server. - Recall that TCP uses port numbers to keep track
of individual conversations. User programs
normally use more or less random port numbers.
However specific port numbers are assigned to the
programs that sit waiting for requests. - For example, if you want to send a file, you will
start a program called "ftp". It will open a
connection using some random number, say 1234,
for the port number on its end. However it will
specify port number 21 for the other end. This is
the official port number for the FTP server. - Note that there are two different programs
involved. - You run ftp on your side. This is a program
designed to accept commands from your terminal
and pass them on to the other end. - The program that you talk to on the other machine
is the FTP server. It is designed to accept
commands from the network connection, rather than
an interactive terminal. There is no need for
your program to use a well-known socket number
for itself. Nobody is trying to find it. However
the servers have to have well-known numbers, so
that people can open connections to them and
start sending them commands. The official port
numbers for each program are given in "Assigned
Numbers".
11Application Protocol (what is a protocol?)
- Once TCP has opened a connection, we have
something that might as well be a simple wire.
All the hard parts are handled by TCP and IP.
However we still need some agreement as to what
we send over this connection (this is the
protocol). In effect this is simply an agreement
on what set of commands the application will
understand, and the format in which they are to
be sent. Generally, what is sent is a combination
of commands and data. They use context to
differentiate. - For example, the mail protocol works like this
- Your mail program opens a connection to the mail
server at the other end. - Your program then sends the mail server
- your machine's name,
- the sender of the message, and
- the recipients you want it sent to.
- It then sends a command saying that it is
starting the message. At that point, the other
end stops treating what it sees as commands, and
starts accepting the message. Your end then
starts sending the text of the message. - At the end of the message, a special mark is sent
(a dot in the first column). - After that, both ends understand that your
program is again sending commands. This is the
simplest way to do things, and the one that most
applications use.
12TSP/IP Highlights
- In the Internet protocol suite, TCP is the
intermediate layer between the Internet Protocol
(IP) below it, and an application above it.
Applications often need reliable pipe-like
connections to each other, whereas the Internet
Protocol does not provide such streams, but
rather only best effort delivery (i.e.,
unreliable packets). - The Transmission Control Protocol (TCP)
guarantees reliable and in-order delivery of data
from sender to receiver. - TCP also distinguishes data for multiple
connections by concurrent applications (e.g., Web
server and e-mail server) running on the same
host. - Applications send byte streams to TCP for
delivery through the network, and TCP divides the
byte stream into appropriately sized segments.
TCP then passes the resulting packets to the
Internet Protocol, for delivery through a network
to the TCP module of the entity at the other end.
- TCP checks to make sure that no packets are lost
by giving each packet a sequence number, which is
also used to make sure that the data are
delivered to the entity at the other end in the
correct order. The TCP module at the far end
sends back an acknowledgement for packets which
have been successfully received.
13Alternatives to TCP
- For many applications TCP is not appropriate. One
big problem is that the application cannot get to
the packets that come after a lost packet, until
the retransmitted copy of the lost packet is
received. This causes problems for real-time
applications such as streaming multimedia (such
as Internet radio) and voice over IP (VoIP) where
it is sometimes more useful to get most of the
data in a timely fashion than it is to get all of
the data in order. - Where TCP is unsuitable, the User Datagram
Protocol (UDP) is used. This provides the
application multiplexing and checksums that TCP
does, but does not handle building streams or
retransmission, giving the application developer
the ability to code those in a way suitable for
the situation and/or to replace them with other
methods like forward error correction or
interpolation.
14What is a Socket?
- An Internet socket (or commonly, a network socket
or socket) is the endpoint of a bidirectional
communication flow across an Internet
Protocol-based computer network, such as the
Internet. - Sockets are a software interface that connects an
application program to a network protocol. - Two processes can communicate by creating sockets
and sending messages through sockets - Information written to a socket by an application
on one machine can be read by an application on
another machine, and vice versa.
15- Communicating local and remote sockets are called
socket pairs. Each socket pair is described by a
unique 4-tuple struct consisting of source and
destination IP addresses and port numbers, i.e.
of local and remote socket addresses. - There are two important socket types
- stream sockets (uses TCP is reliable)
- datagram sockets (uses UDP)
16Socket API (1)
TCP ports
IP
17Overview
- Steps of a TCP Server
- socket() - Get a socket
- bind() - bind to the socket
- listen() - listen for traffic on the socket
- accept() - accept incoming connections on the
socket - recv() - receive incoming traffic
- send() - send traffic to connection
-
- Steps of a TCP Client
- socket() - Get a socket
- connect() - Connect to a server
- send() - send traffic to server
- recv() - receive traffic from server
18- socket() creates a new socket of a certain socket
type, identified by an integer number, and
allocates system resources to it. - bind() is used on the server side, and associates
a socket with a socket address structure, i.e. a
specified local port number and IP address. - listen() is used on the server side, and causes a
bound TCP socket to enter listening state. - connect() is used on the client side, and assigns
a free local port number to a socket. In case of
a TCP socket, it causes an attempt to establish a
new TCP connection. - accept() is used on the server side. It accepts a
received incoming attempt to create a new TCP
connection from the remote client, and creates a
new socket associated with the socket address
pair of this connection. - send() and recv(), or write() and read(), or
recvfrom() and sendto(), are used for sending and
receiving data to/from a remote socket. - close() causes the system to release resources
allocated to a socket. In case of TCP, the
connection is terminated.
19Defining a Socket
- Defining a socket
- include ltsys/types.hgt
- include ltsys/socket.hgt
- int mySocket // a socket descriptor
- SOCKET mySocket // using winsock.h
- CSocket mySocket // MFC sockets
20Creating a Socket
int socket(int protocolFamily,int type,int
protocol)
- First parameter usually PF_INET
- Second parameter socket type
- SOCK_STREAM (TCP)
- SOCK_DGRAM (UDP)
- Third parameter end-to-end protocol.
- Use constants IPPROTO_TCP or IPPROTO_UDP for TCP
or UDP. - Return value is an integer.
- A nonnegative value mean success and can be used
as a handle (similar to file descriptor) - (-1) indicates a failure
mySocket socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)
21Socket API
mySocket socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)
- Sockets API provides a generic interface for a
large number of protocol families. - PF_INET for network protocol
- PF_INET6
- PF_UNIX for local socket (using a file).
- Usually, PF_INET is used to specify a socket that
uses protocols from the Internet protocol family.
22Socket Addressing
mySocket socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)
- When a socket is first created, it has an
associated protocol but no IP address or port
number - A socket descriptor is used by the application to
identify a socket (similar to a file descriptor) - So it can be closed later
- A socket is later bound to an address and a port
number - Otherwise it cannot send/receive messages
23Addresses
- Needed to locate applications running on other
machines - Two pieces of address in TCP/IP
- Internet (or IP) address
- 32-bit binary number (Four 8-bits number)
- dotted-quad notation (e.g. 10.1.2.3)
- refer to a connection (thus, a host can have more
than one IP address) - Port number
- 16-bit unsigned numbers (1 to 65535)
- used by UDP and TCP
- There are multiple ways to specify an address for
a socket - // include ltarpa/inet.hgt
- Res inet_pton(AF_INET, "192.168.1.3",
stSockAddr.sin_addr)
24Internet Addresses
- This is an address that looks like 128.6.4.194.
It is actually a 32-bit number. However it is
normally written as 4 decimal numbers, each
representing 8 bits of the address. - The term "octet" is used by Internet
documentation for such 8-bit chunks. The term
"byte" is not used, because TCP/IP is supported
by some computers that have byte sizes other than
8 bits.) - Generally the structure of the address gives you
some information about how to get to the system.
For example, - 128.6 is a network number assigned by a central
authority to Rutgers University. - Rutgers uses the next octet to indicate which of
the campus Ethernets is involved. 128.6.4 happens
to be an Ethernet used by the Computer Science
Department. - The last octet allows for up to 254 systems on
each Ethernet.
25Ethernet Addresses Advanced (you may skip)
- This is a 48-bit number that is unique to the
Ethernet controller. - The people who designed Ethernet wanted to make
sure that no two machines would end up with the
same Ethernet address. Furthermore, they didn't
want the user to have to worry about assigning
addresses. So each Ethernet controller comes with
an address built-in from the factory. In order to
make sure that they would never have to reuse
addresses, the Ethernet designers allocated 48
bits for the Ethernet address. - People who make Ethernet equipment have to
register with a central authority, to make sure
that the numbers they assign don't overlap any
other manufacturer.
26Specifying Addresses
- Applications using sockets need to specify
Internet addresses and port numbers to the
kernel. - A client must specify the address of a server
application with which it needs to communicate. - The sockets API defines a generic data type for
specifying addresses associated with sockets
struct sockaddr / Structure used by kernel to
store most addresses / unsigned short
sa_family / Address family (AF_INET)/ char
sa_data14 / Family-specific address
/ /
information /
27Internet Address Structure
struct sockaddr_in /socket address
internet style / unsigned short sin_family
/ Address family (AF_INET)/ unsigned short
sin_port / Address port (16 bits) / struct
in_addr sin_addr / Internet Addr (32 bits
/ char sin_zero8 / Not
used/ struct in_addr unsigned long s_addr
28Details of the Address Structure
- These are details showing you that the address
structure are defined as a union to be used in
different ways. But you can specify a given IP
number easily through several Winsock functions. - struct in_addr
- union struct u_char s_b1,s_b2,s_b3,s_b4
S_un_b - struct u_short s_w1,s_w2 S_un_w
- u_long S_addr
- S_un
-
- define s_addr S_un.S_addr
- struct sockaddr_in
- short sin_family
- u_short sin_port
- struct in_addr sin_addr
- char sin_zero8
-
The union stores one of the values defined by
that type 4 bytes or 2 words or 1 long.
You can also set the address using the Winsock
function inet_pton(AF_INET, "192.255.100.4",
stSockAddr.sin_addr)
29gethostname gethostbyname
- The gethostname() function retrieves the standard
host name for the local computer (localhost) - The gethostbyname() function retrieves host
information corresponding to a host name string
from a host database. - You can for instance get your host name, and then
call gethostbyname() to find out your IP address.
30inet_addr
- The inet_addr function converts a string
containing an IPv4 dotted-decimal address into a
proper address for the IN_ADDR structure. - unsigned long inet_addr( const char cp )
- If no error occurs, inet_addr returns an unsigned
long value containing a suitable binary
representation of the Internet address given. - Declared in winsock2.h
- If the string in the cp parameter does not
contain a legitimate Internet address, for
example if a portion of an "a.b.c.d" address
exceeds 255, then inet_addr returns the value
INADDR_NONE. - http//msdn.microsoft.com/en-us/library/ms738563(V
S.85).aspx - USE inet_ntop or inet_pton that replaced these
functions
31Gethost demo
- char buffer128 Â Â Â
- //gets the name of the localhost
- gethostname (buffer,strlen(buffer))
- printf("My hostname s\n", buffer)
- //fills in the hostent structure (see next
slide) - //with the host name
- HOSTENTÂ Â lpHostEnt gethostbyname(buffer)
-
32(No Transcript)
33Hostent structure
- typedef struct hostent
- char FAR h_name
- char FAR FAR h_aliases
- short h_addrtype
- short h_length
- char FAR FAR h_addr_list
- HOSTENT, PHOSTENT, FAR LPHOSTENT
- Note that the possible names we can use for this
struct.
34Getting the Host AddressOther Useful Functions
- The getaddrinfo function provides
protocol-independent translation from host name
to address. - Prototype
- int getaddrinfo( const char nodename, const
char servname, const
struct addrinfo hints, struct addrinfo res) - Parameters
- nodename Pointer to a null-terminated string
containing a host (node) name or a numeric host
address string. The numeric host address string
is a dotted-decimal IPv4 address or an IPv6 hex
address. - servname Pointer to a null-terminated string
containing either a service name or port number. - hints Pointer to an addrinfo structure that
provides hints about the type of socket the
caller supports. -
- res out Pointer to a linked list of one or
more addrinfo structures containing response
information about the host.
This function replaces (is the new version for)
the gethostbyname function (which is commonly
used). See sample codes for complete solutions
for obtaining or setting addresses. Â
35Resolving Host Addresses
- Code from MSDN library to handle different ways
the address structure can be filled (given a host
name or an IP address). You do not need to be
this complete (in error types or diff address
families). - include ltwinsock2.hgt
- include ltws2tcpip.hgt
- include ltstdio.hgt
- include ltwindows.hgt
- pragma comment(lib, "wininet.lib")
- int main(int argc, char argv)
-
- //-----------------------------------------
- // Declare and initialize variables
- WSADATA wsaData
- int iResult
- DWORD dwError
- int i 0
- // If the user input is an alpha name for the
host, use gethostbyname() - // If not, get host by addr (assume IPv4)
- if (isalpha(host_name0)) / host
address is a name / - remoteHost gethostbyname(host_name)
- else
- addr.s_addr inet_addr(host_name)
- if (addr.s_addr INADDR_NONE)
- printf("The IPv4 address
entered must be a legal address\n") - return 1
- else
- remoteHost
gethostbyaddr((char ) addr, 4, AF_INET) -
- if (remoteHost NULL)
- dwError WSAGetLastError()
- if (dwError ! 0)
- if (dwError WSAHOST_NOT_FOUND)
- printf("Host not found\n")
- return 1
36Windows Sockets Client Example 1
- Example
- //Create a socket
- SOCKET theSocket socket (PF_INET,
SOCK_STREAM,
IPPROTO_TCP) - SOCKADDR_IN saServer
- saServer.sin_family AF_INET
- //retrieve host information corresponding to
host name string - LPHOSTENT lpHostEntry gethostbyname(serverName)
- //set the Servers address and port
- saServer.sin_addr.s_addr ((LPIN_ADDR)lpHostEn
try-gth_addr_list) -
- //convert 32-bit values between host and network
byte order - saServer.sin_port htons(nPort)
37htons
- Htons() converts a u_short from host to TCP/IP
network byte order (which is big-endian). - Little Endian (Little End In) the least
significant bytes are stored first in memory - the Hex value 0x1234 is stored in memory as (0x34
0x12). - the Hex value 0x12345678 would be stored as (0x78
0x56 0x34 0x12). - Big Endian (BigEnd In) Most significant bytes
are stored first - 0x1234 is stored as (0x12 0x34) in memory.
38(No Transcript)
39Client
40TCP Client
- A typical TCP client goes through four basic
steps - Create a TCP socket using socket().
- Establish a connection to the server using
connect(). - Communicate using send() and recv().
- Close the connection with close().
41Functions for TCP Client - 1/2
int socket(int protocolFamily, int type, int
protocol)
int connect(int socket, struct sockaddr
serverAddress, unsigned int addressLength)
- Parameters
- First parameterthe descriptor obtained as a
return value of a successful socket creation
operation - Second parameter the address of the server (the
struct data type must appropriately filled by the
server address) - Third parameter always use sizeof(sockaddr).
42What Happens After Connect
socket()
connect()
When a socket is first created, queues
(illustrated above) are closed. During connect,
local port and local IP address is assigned to
it, as well as the remote IP/port.
43Functions for TCP Client - 2/2
int send(int socket, constant void msg,
unsigned int msgLength, int
flags) http//msdn.microsoft.com/en-us/library/m
s740149(VS.85).aspx int recv(int socket, void
rcvBuffer, unsigned int
bufferLength, int flags) http//msdn.microsoft.c
om/en-us/library/ms740121(VS.85).aspx
- Default behavior for send() is to block until all
of the data is sent - Default behavior for recv() is to block until at
least some bytes are received. - flags (default 0) provides a way to change the
default behavior - If no error occurs, recv returns the number of
bytes received and the buffer pointed to by the
buf parameter will contain this data received. If
the connection has been gracefully closed, the
return value is zero. Otherwise, a value of
SOCKET_ERROR is returned, and a specific error
code can be retrieved by calling WSAGetLastError.
If no incoming data is available at the socket,
the recv call blocks and waits for data to arrive
according to the blocking rules defined for
WSARecv with the MSG_PARTIAL flag not set unless
the socket is nonblocking. - send() returns almost immediately, except when
the send buffer is full. If the send buffer is
full, send() blocks until the send buffer is
freed to enqueue another packet. If no error
occurs, send returns the total number of bytes
sent, which can be less than the number requested
to be sent in the len parameter. Otherwise, a
value of SOCKET_ERROR is returned, and a specific
error code can be retrieved by calling
WSAGetLastError.
44Server
45TCP Server
- Four steps of constructing a TCP server
- Create a TCP socket using socket().
- Assign a (local) port number to the socket with
bind(). - Tell the system to allow connections to be made
to that port, using listen(). - Repeatedly do the following
- Call accept() to get a new socket for each client
connection - Communicate with the client via that new socket
using send() and recv().
46Bind
- int bind(int socket, struct sockaddr
localAddress, unsigned int
addressLength)
- First parameter the descriptor returned by an
earlier call to socket(). - Second parameter a pointer to a sockaddr. For
TCP/IP applications, it will actually point to a
sockaddr_in containing IP address of the server
and a port number to listen on - Third parameter use sizeof(sockaddr_in)
- Return value 0 for success 1 for failure
47Windows Sockets Server Example 1(code demoed
in class)
-
- SOCKET listenSocket
- listenSocket socket (PF_INET, // Address
family - SOCK_STREAM, // Socket type
- IPPROTO_TCP) // Protocol
- ...
- SOCKADDR_IN saServer
- saServer.sin_family AF_INET
- saServer.sin_addr.s_addr INADDR_ANY // Let
WinSock supply address - saServer.sin_port htons(nPort) // Use port
from command line -
- // bind the name to the socket
- int nRet bind (listenSocket, // Socket
- (LPSOCKADDR)saServer, // Our
address - sizeof(struct sockaddr)) // Size of address
structure
48Listen
int listen(int socket, int queueLimit)
- Incoming TCP connection requests will be handled
and then queued for acceptance by the program - The queueLimit specifies an upper bound on the
number of incoming connections that can be
waiting at any time - The current socket is only used for listening to
incoming connections and it is not used for
sending and receiving actual data.
49Server Side Under the Hood
socket()
bind()
listen()
50Accept
int accept(int socket, struct sockaddr
clientAddress, unsigned int
addressLength)
- It removes one connection request from the queue.
-
- If no pending connections are present on the
queue and the socket is not marked as
non-blocking, accept() blocks until a connection
is present. - If the socket is marked as non-blocking and no
pending connections are present on the queue,
accept() returns an error. - When successful, accept()
- creates a new socket with the same properties of
socket, and returns a new handle to the socket - fills in the sockaddr structure pointed by the
clientAddress. - returns a descriptor for a new socket that is
connected to the client - The accepted socket is used to read and write
data to and from the socket that connected to it. - The original socket is returned to the listening
state.
51Windows Sockets Server Example 2
-
- nRet listen (listenSocket, // Start listening
to this socket - SOMAXCONN) // Number of
connection request queue - ...
- SOCKET remoteSocket
- remoteSocket accept (listenSocket, //
Listening socket - NULL, // Optional client address
- NULL)
- ...
52Server Side Under the Hood
listen()
accept()
53Client/Server Interaction
54TCP Server vs. TCP Client
- Creating the socket, sending, receiving, and
closing are the same in both party. - The differences
- The server binds an address to the socket
- By calling bind() function
- We say that the server listens to this address
- i.e. underlying TCP protocol implementation waits
for connections from clients by calling listen()
on the socket - The server accepts the connection request
- It gets a new socket for the incoming connection
by calling accept().
55Review
- Steps of a TCP Server
- socket() - Get a socket
- bind() - bind to the socket
- listen() - listen for traffic on the socket
- accept() - accept incoming connections on the
socket - recv() - receive incoming traffic
- send() - send traffic to connection
-
- Steps of a TCP Client
- socket() - Get a socket
- connect() - Connect to a server
- send() - send traffic to server
- recv() - receive traffic from server
56Windows Sockets
- Windows Sockets are based on the UNIX sockets
implementation in the Berkeley Software
Distribution (BSD, release 4.3) - Two socket types are available
- Stream sockets provide for a data flow without
record boundaries a stream of bytes. Streams
are guaranteed to be delivered and to be
correctly sequenced and unduplicated. - Datagram sockets support a record-oriented data
flow that is not guaranteed to be delivered and
may not be sequenced as sent or unduplicated. - Sequenced means that packets are delivered in
the order sent. - Unduplicated means that you get a particular
packet only once.
57Windows Sockets
- Both kinds of sockets are bi-directional they
are data flows that can be communicated in both
directions simultaneously (full-duplex). - The network transport layer may break up or group
data into packets of reasonable size.
58Windows Sockets Client Example 1
- Example
- //Create a socket
- SOCKET theSocket socket (PF_INET,
SOCK_STREAM,
IPPROTO_TCP) - SOCKADDR_IN saServer
- saServer.sin_family AF_INET
- //retrieve host information corresponding to
host name string - LPHOSTENT lpHostEntry gethostbyname(serverName)
- //set the Servers address and port
- saServer.sin_addr.s_addr ((LPIN_ADDR)lpHostEn
try-gth_addr_list) -
- //convert 32-bit values between host and
network byte order - saServer.sin_port htons(nPort)
59Windows Sockets Client Example
- ...
- nRet connect (theSocket,
- (LPSOCKADDR)saServer, // Server address
- sizeof(struct sockaddr)) // Length
of server address structure - ...
- ...
60Windows Sockets Client Example
- printf("Enter the data to be sent to the
server(up to 256 bytes)\n") - gets(szBuf)
- nRet send (theSocket, // Connected socket
- szBuf, // Data buffer
- strlen(szBuf), // Length of data
- 0) // Flags
- ...
- nRet recv (theSocket, // Connected client
- szBuf, // Receive buffer
- sizeof(szBuf), // Max length of
buffer - 0) // Flags
- ...
- closesocket(theSocket)
61Windows Sockets Server Example 1(code demoed
in class)
-
- SOCKET listenSocket
- listenSocket socket (AF_INET, // Address
family - SOCK_STREAM, // Socket type
- IPPROTO_TCP) // Protocol
- ...
- SOCKADDR_IN saServer
- saServer.sin_family AF_INET
- saServer.sin_addr.s_addr INADDR_ANY // Let
WinSock supply address - saServer.sin_port htons(nPort) // Use port
from command line -
- // bind the name to the socket
- int nRet bind (listenSocket, // Socket
- (LPSOCKADDR)saServer, // Our
address - sizeof(struct sockaddr)) // Size of address
structure
62Windows Sockets Server Example 2
-
- nRet listen (listenSocket, // Start listening
to this socket - SOMAXCONN) // Number of
connection request queue - ...
- SOCKET remoteSocket
- remoteSocket accept (listenSocket, //
Listening socket - NULL, // Optional client address
- NULL)
- ...
63Windows Sockets Server Example 3
-
- nRet recv (remoteSocket, // Connected client
- szBuf, // Receive buffer
- sizeof(szBuf), // Length of buffer
- 0) // Flags
- ...
- nRet send (remoteSocket, // Connected socket
- szBuf, // Data buffer
- strlen(szBuf), // Length of data
- 0) // Flags
- ...
- closesocket(remoteSocket)
- closesocket(listenSocket)
64Winsock DLL
- The WSAStartup function must be the first Windows
Sockets function called by an application or DLL.
- WORD wVersionRequested MAKEWORD(1,1)
- //include winsock.h if higher versions, may
need winsock2.h - WSADATA wsaData
- int nRet
-
- // Initialize WinSock and check version
- nRet WSAStartup(wVersionRequested, wsaData)
- if (wsaData.wVersion ! wVersionRequested)
-
- fprintf(stderr,"\n Wrong version\n")
- return
-
- Complete info (latest versions etc)
- http//msdn2.microsoft.com/en-us/library/ms742213.
aspx
65Winsock DLL
- The WSACleanup function terminates use of the
Winsock 2 DLL (Ws2_32.dll). - Sockets that were open when WSACleanup was called
are reset and automatically deallocated as if
closesocket were called. - //Release Winsock DLL
- WSACleanup()
-
- Complete info (latest versions etc)
- http//msdn2.microsoft.com/en-us/library/ms741549.
aspx
66- You are given the necessary info to setup a
socket connection - You will need to check the MSDN documentation to
find more details.
67- We must close all opened sockets when done.
- Closing a socket
int close(int socket) //for UNIX int
closesocket(SOCKET socket) //for Windows
- the parameter is the socket descriptor obtained
as return value of a successful socket creation
operation - Return value of (0) means success, (-1) indicates
a failure
closesocket(mySocket)
68Code Samples
- See the sample code in SocketExample
- This is a basic code using all of the Winsock API
that is necessary to setup a very simple socket
connection - You are also shown hw5-2007
- You can run two versions of this program
(hw5exe) - Start one as server
- Star one as client (even though they are more
like peers) - Think about what are the threads running in this
program - One thread handles the user interface and does
the send operation - One thread listens to any incoming messages (from
the other party) - You should be able to answer the following
- How many threads do you need? For what?
- Can send and receive be in the same thread?
69Hw5-2009
70Socket Program Example
- Hw5 2007
- (Not this years homework)
71Demo Hw5
- Run (using !) hw5-demo.exe
- Start as server
- Run (using !) hw5-demo.exe
- Start as client //must come after the server
- Draw shapes and see the server and client
communicate - Once the communication is done, each program
should work as before , on its own
72(No Transcript)
73Hints Socket Class for Hw5
- class CClientSocket
-
- SOCKET mySocket
- int Port //port number
- char Server //server's name
- char Buffer //buffer is char array
- int MaxBuffer //maximum buffer
size - ..
- public
- CClientSocket(..) //constructor
- virtual CClientSocket() //destructor
- void Connect()
- int Read()
- void Send(.)
-
- //You will need to fill-in parameters where dots
are.
74Hints Starting as Server or Client
- Start as server or client
- client new CClientSocket("localhost",9999,256,
this) - server new CServerSocket(9999,256,this)
- You may connect to localhost which is a
reserved name for your own computer (where the
program refering to localhost is running) -
- You may also connect to your friends machine as
needed, by specifying the server (through command
line arguments or program settings, as we have
done before)
75Hint Start as Server
- The relationship between the socket and thread
may be as follows (but can be different as well) - void CDrawViewOnStartAsServer()
-
- .
- //create a socket using arbitrary parameters
- server new CServerSocket(9999,1000,this)
- //Listen and accept
- server-gtListen()
- if(connected)
-
- MessageBox("A Client Connected") //inform the
user - myThread new CMyThread(this) //create
thread to read messages - myThread-gtStart() //start thread
-
76Hint thread class
- class CMyThread
-
- public
- CMyThread(CDrawView parent) virtual
CMyThread() - int Start()
- void Run()
- void Close()
- private
- CDrawView Parent //handle to CDrawView
-
- static UINT ThreadFunc (LPVOID pParam)
-
- Note this is just one possibility, you can
construct your thread differently
77Hint thread class
- int CMyThreadStart()
-
- pThreadAfxBeginThread()
-
-
- UINT CMyThreadThreadFunc(LPVOID pParam)
-
- .
-
- You would need to fill these out, if you use this
class given as hint.
78Hints Starting as Server or Client
- void CMyThreadRun()
-
- char buffer
- while (1)
- try
- if (Parent-gtIsServer())
- nRet Parent-gtserver-gtRead(buffer)
- if (nRet -1)
- throw ..
-
- else
- nRet Parent-gtclient-gtRead(buffer)
- if (nRet -1)
- throw ..
-
-
- catch (char str)
-
- Parent-gtMessageBox(str)
79Synchronization
- You dont need synchronization (Mutex objects)
for this homework. - There may be a slight need , like elements being
inserted into the list in the wrong order if both
parties draw at the same time, but this is too
small, unimportant for this homework
80- Winsock reference and info can be found at
- http//msdn.microsoft.com/en-us/library/ms738524(V
S.85).aspx - This is where you will find non-specified usage
specs for wisnsock related functions (e.g.
Gethostbyname, hostent struct, htons, inet_ntoa,
WSAStartup) - The gethostbyname function cannot resolve IP
address strings passed to it. Such a request is
treated exactly as if an unknown host name were
passed. Use inet_addr to convert an IP address
string to an actual IP address, then use another
function, gethostbyaddr, to obtain the contents
of the hostent structure.
81UNIX Examples
- SKIP IF NOT INTERESTED
- The concepts are the same, but the API is
different
82UNIX example TCPEchoClient.c - 1/4
- include ltstdio.hgt / for printf()
/include ltsys/socket.hgt / for
socket(), connect(), send()
and recv() / include
ltarpa/inet.hgt / for sockaddr_in and inet_addr()
/include ltstdlib.hgt / for atoi()
/include ltstring.hgt / for
memset() /include
ltunistd.hgt / for close()
/ - define RCVBUFSIZE 32 / Size of receive buffer
/ - void DieWithError(char errorMessage) / error
handling function / - int main(int argc, char argv)
- int sock struct sockaddr_in echoServAddr
unsigned short echoServPort char servIP
...
83TCPEchoClient.c - 2/4
- ...int main(int argc, char argv) ...
- char echoString char echoBufferRCVBUFSIZE
unsigned int echoStringLen int bytesRcvd,
totalBytesRcvd - if (argc ! 2)) printf(Usage s
ltServer IPgt ltEcho Wordgt \n, argv0)
exit(1) - servIP argv1 echoString argv2
echoServPort 7 / well-known port for echo
service / ...
84TCPEchoClient.c - 3/4
- ... / Create a reliable, stream socket using
TCP / if(sock socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 0) DieWithError(socket()
failed) - / Construct the server address structure /
memset(echoServAddr, 0, sizeof(echoServAddr)
echoServAddr.sin_family AF_INET / Convert
Servers IP address string to proper IP address
/ - echoServAddr.sin_addr.s_addr
inet_addr(ServIP) - / Convert the port num to proper order /
- echoServAddr.sin_port htons(echoServPort)
- / Establish a connection to the echo server
/ if(connect(sock, (struct sockaddr )
echoServAddr, sizeof(echoServAddr)) lt 0)
DieWithError(socket() failed) - echoStringLen strlen(echoString) /Determine
the input length / - ...
85TCPEchoClient.c - 4/4
- ... / Send the string to the server /
if(send(sock, echoString, echoStringLen, 0)) !
echoStringLen) DieWithError(send()
failed) - / receive the same string back from the server
/ totalBytesRcvd 0 printf(Received )
while (totalBytesRcvd lt echoStringLen)
if(bytesRcvd recv(sock, echoBuffer, RCVBUFSIZE
- 1, 0)) lt 0) DieWithError(socket()
failed) - totalBytesRcvd bytesRcvd
echobufferbytesRcvd \0
printf(echoBuffer) - prinft(\n) close(sock) exit(0)
86TCPEchoServer.c 1/4
- include ltstdio.hgt / for printf() and
fprintf() /include ltsys/socket.hgt / for
socket(), connect(), send()
and recv() / include
ltarpa/inet.hgt / for sockaddr_in and inet_addr()
/include ltstdlib.hgt / for atoi()
/include ltstring.hgt / for
memset() /include
ltunistd.hgt / for close()
/ - define MAXPENDING 5 / Maximum outstanding
conn. requests / - void DieWithError(char errorMessage) / error
handling func. /void HandleTCPclient(int
clntSocket) / for TCP client handling
function / - int main(int argc, char argv)
- int ServSock, clntSock
- struct sockaddr_in echoServAddr
- struct sockaddr_in echoClntAddr
- unsigned short echoServPort unsigned int
clntLen / Length of client address data
structure
/ ...
87TCPEchoServer.c 2/4
- ...int main(int argc, char argv) ...
- echoServPort 7 / well-known port for echo
service / - / Create socket for incoming connections /
if((servSock socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 0) DieWithError(socket()
failed) - / Construct Local address structure /
memset(echoServAddr, 0, sizeof(echoServAddr)
echoServAddr.sin_family AF_INET
echoServAddr.sin_addr.s_addr htonl(INADDR_ANY)
echoServAddr.sin_port htons(echoServPort)
...
88TCPEchoServer.c 3/4
- ...int main(int argc, char argv) ...
- / Bind to the local address /
if(bind(servSock, (sturct sockaddr )
echoServAddr, sizeof(echoServAddr)) lt 0)
DieWithError(bind() failed) - / Mark the socket so it will listen for
incoming connections / if(listen(servSock,
MAXPENDING) lt 0) DieWithError(listen()
failed) ...
89TCPEchoServer.c 4/4
- ...int main(int argc, char argv) ...
- for()
- / Wait for a client to connect /
if((clntSock accept(servSock, (struct
sockaddr ) echoClntAddr, sizeof(echoClntAddr))
lt 0) DieWithError(bind() failed) - / clntSock is connected to a client /
- printf(Handling client s\n,
inet_toa(echoClntAddr.sin_addr)) - HandleTCP(clntSock) / NOT
REACHED /
90HandleTCPClient.c 1/2
- include ltstdio.hgt / for printf() and
fprintf() /include ltsys/socket.hgt / for
send() and recv() / include
ltunistd.hgt / for close()
/ - define RCVBUFSIZE 32
- void DieWithError(char errorMessage) / error
handling func. / - void HandleTCPclient(int clntSocket)
- char echoBufferRCVBUFSIZE int
recvMsgSize - / Receive message from client /
if((recvMsgSizerecv(clntSocket, echoBuffer,
RCVBUFSIZE, 0)) lt 0) DieWithError(recv()
failed) - ...
91HandleTCPClient.c 2/2
- ...
- / Send received string and receive again until
the end of transmission /
while(recvMsgSize gt 0) / zero indicates end of
transmission / - / Echo message back to client /
if(send(clntSock, echoBuffer, recvMsgSize, 0)) !
recvMsgSize) DieWithError(send()
failed) - / Receive message from client /
if((recvMsgSizerecv(clntSock, echoBuffer,
RCVBUFSIZE, 0)) lt 0) DieWithError(recv()
failed) -
- close(clntSocket)
-
92MFCs CSocket Class
- This class has some problems (did not work for us
and is reported to have some problems), so we
will skip this. Anyway it is just a wrapper
around the Windows sockets.
93MFC CSockets
- Class based on Windows Sockets
- CSocket mysocket
- Main gain is that CSockets allows you to use
CArchive to send/receive Serializable objects,
without converting them into a byte string. - e.g. a rectangle shape object is sent
automatically (not first sending the top-left
point coordinates, then ...)
94Csocket Class
95Csocket Class
- A CArchive object manages a buffer. When the
buffer of a storing (sending) archive is full, an
associated CFile object writes out the buffer's
contents. - Flushing the buffer of an archive attached to a
socket is equivalent to sending a message. When
the buffer of a loading (receiving) archive is
full, the CFile object stops reading until the
buffer is available again. - Class CSocketFile derives from CFile, but it does
not support CFile member functions (Seek,
GetLength, ...). - All the CSocketFile object must do is write or
read sequences of bytes to or from the associated
CSocket object. Because a file is not involved,
operations such as Seek and GetPosition make no
sense. - CSocketFile is derived from CFile, so it would
normally inherit all of these member functions.
To prevent this, the unsupported CFile member
functions are overridden in CSocketFile to throw
a CNotSupportedException. - The CSocketFile object calls member functions of
its CSocket object to send or receive data.
96Csocket Class http//msdn.microsoft.com/library/d
efault.asp?url/library/en-us/vccore98/HTML/_core_
windows_sockets.3a_.sequence_of_operations.asphtt
p//msdn.microsoft.com/library/default.asp?url/li
brary/en-us/vccore/html/_core_Windows_Sockets_in_M
FC.asp
- SERVER
- // construct a socket
- CSocket sockSrvr
- // bind to the port
- sockSrvr.Create(nPort)1,2
- // start listening
- sockSrvr.Listen( )
- -------
- CLIENT
- // construct a socket
- CSocket sockClient
- // create the SOCKET
- sockClient.Create( )2
- -------
- // seek a connection
- sockClient.Connect(svrAddr,nPort)3,4
same
97Csocket Class
- CLIENT ctd.
- -------
- // construct file object
- CSocketFile file(sockClient)
- SERVER ctd.
- ...
- // construct a new, empty socket
- CSocket sockRecv
- // accept connection
- sockSrvr.Accept(sockRecv) 5
- // construct file object
- CSocketFile file(sockRecv)
98Csocket Class
- SERVER OR CLIENT
- // construct an archive
- CArchive arIn (file,CArchiveload) or
- CArchive arOut (file,CArchivestore)
- // use the archive to pass data
- arIn gtgt dwValue or
- arOut ltlt dwValue6
99Footnotes for the Previous Slides
- 1. Where nPort is a port number.
- 2. The server must always specify a port so
clients can connect. The Create call sometimes
also specifies an address. On the client side,
use the default parameters, which ask MFC to use
any available port. - 3. Where nPort is a port number and strAddr is a
machine address or an Internet Protocol (IP)
address. - 4. Machine addresses can take several forms
ftp.microsoft.com, ucsd.edu. IP addresses use
the dotted number form 127.54.67.32. The
Connect function checks to see if the address is
a dotted number (although it doesnt check to
ensure the number is a valid machine on the
network). If not, Connect assumes a machine name
of one of the other forms. - 5. When you call Accept on the server side, you
pass a reference to a new socket object. You must
construct this object first, but do not call
Create for it. Keep in mind that if this socket
object goes out of scope, the connection closes.
MFC connects the new object to a SOCKET handle.
You can construct the socket on the stack, as
shown, or on the heap. - 6. The archive and the socket file are closed
when they go out of scope. The socket objects
destructor also calls the Close member function
for the socket object when the object goes out of
scope or is deleted.
100CSocket.Create()
- BOOL Create ( Â Â Â Â Â Â Â Â UINT nSocketPort 0,
        int nSocketType SOCK_STREAM,
        long lEvent FD_READ FD_WRITE
FD_OOB FD_ACCEPT FD_CONNECT FD_CLOSE,
        PCTSTR lpszSocketAddress NULL) - nSocketPort - A port for our socket. If zero (it
is the default) MFC will choose it automatically.
- nSocketType -Â Type of our socket. SOCK_STREAM
for connection oriented sockets and SOCK_DGRAM
for connections message oriented sockets. - lEvent - Events that user wants receive
notifications for them. For example if FD_READ is
included then OnReceive method will be called (of
course when this event will occur). Default value
means that all notifications are included. - lpszSocketAddress - Address of our host to which
we want bind our socket. If it's NULL (it's
default) then one can bind socket with Bind
method. - Returned value is non zero on success and zero
otherwise. Specific error code can be accepted
through GetLastError method.
101Further Info - Useful Sites
- MSDN help files or on the web
- http//msdn.microsoft.com
- http//www2.rad.com/networks/1999/sockets/SockMFC
.htm