Lecture-12-Windows_Sockets
Lecture-12-Windows_Sockets
Muhammad Zeeshan
Sabir
What is a socket?
An interface between application and
network
The application creates a socket
The socket type dictates the style of
communication
• reliable vs. best effort
• connection-oriented vs. connectionless
Once configured the application can
pass data to the socket for network
transmission
receive data from the socket (transmitted
through the network by some other host)
2
A Socket-eye view of the
Internet
medellin.cs.columbia.edu
(128.59.21.14)
newworld.cs.umass.edu
(128.119.245.93)
cluster.cs.columbia.edu
(128.59.21.14,
128.59.16.7, 128.59.16.5,
128.59.16.4)
3
Ports
Each host has
Port 0
65,536 ports
Port 1
Some ports are
reserved for specific
Port 65535
apps
20,21: FTP A socket provides an
23: Telnet
interface to send data
80: HTTP to/from the network through
a port
see RFC 1700 (about
2000 ports are
reserved)
4
Two essential types of
sockets
SOCK_STREAM SOCK_DGRAM
a.k.a. TCP a.k.a. UDP
reliable delivery unreliable delivery
in-order guaranteed no order guarantees
connection-oriented no notion of “connection”
bidirectional – app indicates dest. for
each packet
can send or receive
App
3 2 App D1
1
socket Dest.
3 2
1
socket D2
D3
5
Simple Client-Server Example
response
Client Server
request
socket()
bind()
socket() listen()
Connection
connect() establishment accept()
send()
Data request recv()
8
Skipping the bind
SOCK_DGRAM:
if only sending, no need to bind. The OS
finds a port each time the socket sends a
pkt
if receiving, need to bind
SOCK_STREAM:
destination determined during conn. setup
don’t need to know port sending from
(during connection setup, receiving end is
informed of port)
9
Connection Setup
(SOCK_STREAM)
Recall: no connection setup for SOCK_DGRAM
A connection occurs between two kinds of
participants
passive: waits for an active participant to request
connection
active: initiates connection request to passive side
Once connection is established, passive and
active participants are “similar”
both can send & receive data
either can terminate the connection
10
IP Address Data Structure
struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8];
};
struct in_addr {
unsigned long s_addr; // 4 bytes
};
11
connect(): Making TCP
Connection to Server
struct sockaddr_in sin;
A B C D
0 1 2 3 4 5 6 7 8 9
slide through
receive
buffer
Use records (data structures) to
partition the data stream
14
Receiving Packets
int receive_packets(char *buffer, int buffer_len, int *bytes_read)
{
int left = buffer_len - *bytes_read;
received = recv(chat_sock, buffer + *bytes_read, left, 0);
if (received < 0) { buffer_len
perror (“recv"); buffer
}
if (received <= 0) {
return close_connection();
}
*bytes_read += received; *bytes_read
while (*bytes_read > RECORD_LEN) {
process_packet(buffer, RECORD_LEN);
*bytes_read -= RECORD_LEN;
memmove(buffer, buffer + RECORD_LEN, *bytes_read);
}
return 0;
}
16
bind(): Assign
struct sockaddr_in sin;
IP and Port
struct hostent *host = gethostbyname (argv[1]);
unsigned int server_address = *(unsigned long *) host->h_addr_list[0];
unsigned short server_port = atoi (argv[2]);
17
bind():
bind() tells the OS to assign a local IP address
and local port number to the socket.
Many applications let the OS choose an IP
address.
Use wildcard INADDR_ANY as local address in this case.
At server, user process must call bind() to
assign a port
At client, bind() is not required since OS may
assign available port and IP address
The server will get the port number of the client
through the UDP/TCP packet header
Note: Each application is represented by a
server
CEN4500C
port number 18
listen(): Wait for
Connections
int listen(int sockfd, int backlog);
19
Server Example
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
int main(void) {
int sockfd, new_fd; // listen on sockfd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int sin_size;
20
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
close(new_fd);
}
return 0;
}
CEN4500C
21
Connection setup cont’d
Passive participant Active participant
step 1: listen (for
incoming requests)
step 3: accept (a
step 2: request &
establish connection
request)
step 4: data transfer
step 4: data transfer
The accepted
connection is on a Passive Participant
new socket a-sock-1 l-sock a-sock-2
The old socket
continues to listen
for other active
participants socket socket
Active Active 2
22
1
Connection setup: listen &
accept
Called by passive participant
int status = listen(sock, queuelen);
status: 0 if listening, -1 if error
sock: integer, socket descriptor
queuelen: integer, # of active participants that can “wait”
for a connection
listen is non-blocking: returns immediately
int s = accept(sock, &name, &namelen);
s: integer, the new socket (used for data-transfer)
sock: integer, the orig. socket (being listened on)
name: struct sockaddr, address of the active participant
namelen: sizeof(name): value/result parameter
• must be set appropriately before call
• adjusted by OS upon return
accept is blocking: waits for connection before returning
23
connect call
int status = connect(sock, &name, namelen);
status: 0 if successful connect, -1 otherwise
sock: integer, socket to be used in
connection
name: struct sockaddr: address of passive
participant
namelen: integer, sizeof(name)
connect is blocking
24
Sending / Receiving Data
With a connection (SOCK_STREAM):
int count = send(sock, &buf, len, flags);
• count: # bytes transmitted (-1 if error)
• buf: char[], buffer to be transmitted
• len: integer, length of buffer (in bytes) to transmit
• flags: integer, special options, usually just 0
int count = recv(sock, &buf, len, flags);
• count: # bytes received (-1 if error)
• buf: void[], stores received bytes
• len: # bytes received
• flags: integer, special options, usually just 0
Calls are blocking [returns only after data is
sent (to socket buf) / received]
25
Sending / Receiving Data
(cont’d)
Without a connection (SOCK_DGRAM):
int
count = sendto(sock, &buf, len, flags, &addr,
addrlen);
• count, sock, buf, len, flags: same as send
• addr: struct sockaddr, address of the destination
• addrlen: sizeof(addr)
int count = recvfrom(sock, &buf, len, flags, &addr,
&addrlen);
• count, sock, buf, len, flags: same as recv
• name: struct sockaddr, address of the source
• namelen: sizeof(name): value/result parameter
Calls are blocking [returns only after data is sent
(to socket buf) / received]
26
close
When finished using a socket, the
socket should be closed:
status = close(s);
status: 0 if successful, -1 if error
s: the file descriptor (socket being closed)
Closing a socket
closes a connection (for SOCK_STREAM)
frees up the port used by the socket
27
The struct sockaddr
The generic: The Internet-specific:
struct sockaddr { struct sockaddr_in {
u_short sa_family; short sin_family;
char sa_data[14]; u_short sin_port;
}; struct in_addr sin_addr;
char sin_zero[8];
sa_family
};
sin_family = AF_INET
• specifies which
sin_port: port # (0-65535)
address family is
sin_addr: IP-address
being used
sin_zero: unused
• determines how
the remaining 14
bytes are used
28
select function call
int status = select(nfds, &readfds, &writefds,
&exceptfds, &timeout);
status: # of ready objects, -1 if error
nfds: 1 + largest file descriptor to check
readfds: list of descriptors to check if read-ready
writefds: list of descriptors to check if write-ready
exceptfds: list of descriptors to check if an
exception is registered
timeout: time after which select returns, even if
nothing ready - can be 0 or
(point timeout parameter to NULL for )
29
Release of ports
Sometimes, a “rough” exit from a program
(e.g., ctrl-c) does not properly free up a port
Eventually (after a few minutes), the port will
be freed
To reduce the likelihood of this problem,
include the following code:
#include <signal.h>
void cleanExit(){exit(0);}
in socket code:
signal(SIGTERM, cleanExit);
signal(SIGINT, cleanExit);
30