Error handling
Berkeley Sockets
- Generic:
- support for multiple protocol families.
- address representation independence
- Uses existing I/O programming interface as much as possible.
Socket
- A socket is an abstract representation of a communication endpoint.
- Sockets work with Unix I/O services just like files, pipes & FIFOs.
- Sockets (obviously) have special needs:
- establishing a connection
- specifying communication endpoint addresses
Unix Descriptor Table
Socket Descriptor Data Structure
Creating a Socket
int socket(int family,int type,int proto);
- family specifies the protocol family (PF_INET for TCP/IP).
- type specifies the type of service (SOCK_STREAM, SOCK_DGRAM).
- protocol specifies the specific protocol (usually 0 which means the default).
socket()
- The socket() system call returns a socket descriptor (small integer) or a -1 on error.
- socket() allocates resources needed for a communication endpoint - but it does not deal with endpoint addressing.
Specifying an Endpoint Address
- Remember that the sockets API is generic.
- There must be a generic way to specify endpoint addresses.
- TCP/IP requires an IP address and a port number for each endpoint address.
- Other protocol suites (families) may use other schemes.
Generic socket addresses
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
- sa_family specifies the address type.
- sa_data specifies the address value.
sockaddr
- An address that will allow me to use sockets to communicate with my kids.
- address type AF_DAVESKIDS
- address values:
- Andrea 1
- Jeff 2
- Robert 3
- Emily 4
- Mom 5
- Dad 6
- Dog 7
AF_DAVESKIDS
AF_INET
- For AF_DAVESKIDS we only needed 1 byte to specify the address.
- For AF_INET we need:
- 16 bit port number
- 32 bit IP address
struct sockaddr_in
struct sockaddr_in {
u_short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr
struct in_addr {
u_long s_addr; /* IP ADDRESS */
};
in_addr just provides a name for the 'C' type associated with IP addresses.
Network Byte Order
- All values stored in a sockaddr_in must be in network byte order.
- sin_port a TCP/IP port number.
- sin_addr an IP address.
TCP/IP Addresses
- We don't need to deal with sockaddr structures since we will only deal with one protocol family.
- We can always use sockaddr_in structures.
- The C functions that make up the sockets API expect structures of type sockaddr.
Assigning an address to a socket
bind()
bind() Example
int mysock;
struct sockaddr_in myaddr;
mysock = socket(PF_INET,SOCK_STREAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( portnum );
myaddr.sin_addr = htonl( ipaddress);
bind(mysock, &myaddr, sizeof(myaddr));
Uses for bind()
- There are 3 uses for bind():
- Server would like to bind to a well known address (port number).
- Client can bind to a specific port.
- Client can ask the O.S. to assign any available port number.
Port schmort - who cares ?
- Clients typically don't care what port they are assigned.
- When you call bind you can tell it to assign you any available port:
myaddr.port = htons(0);
What is my IP address ?
- How can you find out what your IP address is so you can tell bind() ?
- There is no realistic way for you to know the right IP address to give bind() - what if the computer has multiple network interfaces?
- specify the IP address as: INADDR_ANY, this tells the OS to take care of things.
Other socket system calls
- General Use
- Connection-oriented (TCP)
- connect()
- listen()
- accept()
- Connectionless (UDP)