Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

2.

Socket programming basics


What is Socket (or Socket API)?

• Socket: an end-point in Internet (a combination of an IP


address, port no., protocol no.)
• Socket Interface/API: a library for inter-process communication
over network/Internet
– Introduced in BSD Unix 4.1 (1982)
– Provided in most of dev. platforms (de facto standard)
– E.g., Winsock, Java.net.Socket
5-7 Appl. 1 Appl. 2 Appl. 3
Socket interface

Socket 1 Socket 2 Socket 3

4
3 TCP/IP

2
Network driver
1
Socket number (1)

• In Unix, everything is a file (i.e., a device is represented as a file)


– Keyboard, monitor, socket, etc.
• Socket descriptor
– File descriptor linked to a socket (assgind when a socket is open)
– Communicate like file reads/writes

Descriptor table File or socket structure


..
.. .
.
(file)
3 pointer
family : PF_INET
File/socket (file)
4 pointer service : SOCK_STREAM
descriptor
(socket)
5 pointer local IP :

local port :
..
. remote IP :

remote port :

..
Socket number (2)

• Relationship among application, socket, and TCP/IP

Connection-oriented
연결형 서비스 services connectionless
비연결형 서비스 services

응용 1 응용 2 응용 3 응용 4
응용 프로그램
fd=3 sd=4 sd=3 sd=3 sd=3 (소켓번호)

소 켓

3000 3001 2000 2001 (포트 번호)


포트
port 트랜스포트 계층
TCP UDP

IP 인터넷 계층
TCP/IP
192.203.144.11 (IP 주소)

fd : File Descriptor 네트워크


sd : Socket Descriptor
Network
IP : Internet Protocol
TCP : Transmission Control Protocol
UDP: User Datagram Protocol
Port number

• IP address
– Used to identify a host and deliver IP datagrams to destinations
• Port number
– 16 bit number used to identify a process on a host
– Two different protocols (TCP, UDP) can share a port number
• Well-known ports
– Port numbers under 1024
– Predefined
– ex) ftp, telnet, mail, http, etc.
• /etc/services
– defines network (or TCP/IP) services and their port numbers
Socket creation

• Socket is not solely for TCP/IP communication


– Socket can be used with other protocol suites than TCP/IP
– Use domain to select a protocol family to use
#include <sys/socket.h>
int socket(
int domain,
int type,
int protocol);

• Protocol family available


PF_INET // IPv4
PF_INET6 // IPv6
PF_UNIX // Local communication
PF_PACKET // Low level packet interface

• types available
SOCK_STREAM // TCP socket
SOCK_DGRAM // UDP socket
SOCK_RAW // Raw socket
Socket examples

• To do
– Open two files (/etc/passwd, /etc/hosts) and two sockets.
Then, prints their descriptor numbers

// passwd file open


fd1 = open(“/etc/passwd”, O_REONLY, 0); // 3
printf(“/etc/passwd’s file descriptor = %d\n”, fd);

// creation of a stream type socket


sd1 = socket(PF_INET, SOCK_STREAM, 0); // 4
printf(stream socket descriptor = %d\n”, sd1);

// datagram type socket open


sd2 = socket(PF_INET, SOCK_DGRAM, 0); // 5
printf(datagram socket descriptor = %d\n”, sd2);

// host file open


fd2 = open(“/etc/hosts”, O_REONLY, 0); // 6
printf(“/etc/host’s file descriptor = %d\n”, fd2);
Socket related

• Full information needed before communicate


– Protocol (e.g., TCP, UDP)
– Source IP address
– Source port number
– Destination IP address
– Destination port number

• Limitation on socket/file descriptor number


– In UNIX defined in <sys/types.h> as FD_SETSIZE
– getdtablesize() gives the max number of concurrent open files
#include <stdio.h>
#include <unistd.h>

printf(“getdtablesize(0 \ %d\n”, getdtablesize());


Socket C programming

• Location of C headers in UNIX


/usr/include
/usr/include/sys
/usr/include/netinet

• man page
– Use to retrieve information about APIs/functions
$ man socket
Network Functions socket(3N)

NAME
socket - create an endpoint for communication

SYNOPSIS
cc [ flag ... ] file ... -lsocket -lnsl [ library ... ]
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

DESCRIPTION
socket() creates an endpoint for communication .....
Structure for socket address - sockaddr

• To represent addresses used in socket API


– Address family (주소체계)
– IP address
– Port number

struct sockaddr {
u_short sa_family; // address family
char sa_data[14]; // address
};

• socketaddr: difficult to use


– sockaddr_in: use instead
sockaddr_in structure

• in_addr structure is used in sockaddr_in

struct in_addr {
u_long s_addr; // used to hold a 32bit IP address
};

struct sockaddr_in {
short sin_family; // address familty
u_short sin_port; // 16bit port
struct in_addr sin_addr; // 32bit IP address
char sin_zero[8]; // padding (to make the total size 16byte)
};

• sin_family

AF_INET // IPv4 address


AF_UNIX // UNIX address
Function call timeline

• TCP(connection-oriented) socket
서 버
Server 클라이언트
Client

socket() socket()

bind()

listen()
Connection connect()
연결요청
request

accept()

데이터 송수신
Exchange of data
send() recv()
recv() send()

Connection
termination
종료
close()
2.2 Internet address translation
Byte order

• Host byte order


– Order of byte-size data being stored in memory
– Depends on CPU types
• Intel x86 : little-endian
• SPARC : big-endian
• Network byte order
– Order of bytes being transmitted in a multi-byte field (e.g., port
no., IP address)
– big-endian
• Problems in communicating between Intel x86 and SPARC
CPUs?

주 소: n n+1 n n+1
데이터 : E2 C3 C3 E2

(a) little-endian (b) big-endian


(80x86 계열) (MC68000계열)
Functions related to byte orders

• Use different functions for 2-byte data and 4-byte data


– Unsigned short (2-byte) case

htons() : host-to-network byte order translation


ntohs() : network-to-host byte order translation

– Unsigned long (4-byte) case

htonl() : host-to-networkbyte order translation


ntohl() : network-to-hostbyte order translation
byte_order.c (1)

• An example showing host/network byte order difference


– getservbyname() system call
pmyservent = getservbyname(“echo”, “udp”);

– servent structure
struct servent {
char *s_name;
char **s_aliases;
int s_port;
char *s_proto;
};
byte_order.c (2)

• Srouce code
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(void) {
struct servent *serv = getservbyname("echo", "udp");
if (serv == NULL) {printf( “Information unavailable.\n"); exit(0);}

printf("UDP echo port no.(network byte order) : %d \n", serv->s_port);


printf("UDP echo port no.(host byte order) : %d \n", ntohs(serv->s_port));

return 0;
}

• Results
// On SPARC systems
$ byte_order
UDP echo port no.(network byte order) : 7
UDP echo port no.(host byte order) : 7

// On Intel x86 PCs


$ byte_order
UDP echo port no.(network byte order) :1792
UDP echo port no.(host byte order) : 7
IP address translation

• Converting among domain name, IP address, and dotted decimal rep.


– A dotted decimal representation is a 15-byte string
• Functions for conversion between IP address and dotted decimal
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

const char *inet_ntop(int af, const void *src, char *dst, size_t cnt);
int inet_pton(int af, const char *src, void *dst);

cc.kangwon.ac.kr : 11000000110010111001000000001011 : 192.203.144.11


dotted
도메인 네임 IP 주소 (binary)
decimal

gethostbyname() inet_pton()

gethostbyaddr() inet_ntop()
ascii_ip.c

• Convert dotted decimal address into 4-byte IP address and


vice versa
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <netdb.h>

14
15 int main(int argc, char *argv[]) {
16 struct in_addr inaddr; 17 char buf[20];
18
23 printf("* Input dotted decimal address: %s\n", argv[1]);
24
25 inet_pton(AF_INET, argv[1], &inaddr.s_addr);
26 printf(" inet_pton(%s) = 0x%X\n", argv[1], inaddr.s_addr);
27 inet_ntop(AF_INET, &inaddr.s_addr, buf, sizeof(buf));
28 printf(" inet_ntop(0x%X) = %s\n", inaddr.s_addr,buf);
29
30 return 0;
31 }

• Results
$ ascii_ip 210.15.36.231
* Input dotted decimal address : 210.15.36.231
inet_pton(210.115.36.231) = 0xE72473D2
inet_ntop(0xE72473D2) = 210.115.36.231
Translating domain name

• DNS (Domain Name System)


– Translate domain names to IP addresses (& vice versa)

• Translation functions
#include <netdb.h>
struct hostent *gethostbyname(const char *hname);
struct hostent *gethostbyaddr(const char *in_addr, int len, int family);

cc.kangwon.ac.kr : 11000000110010111001000000001011 : 192.203.144.11


dotted
도메인 네임 IP 주소 (binary)
decimal

gethostbyname() inet_pton()

gethostbyaddr() inet_ntop()
Translating domain name (cont.)

• gethostbyname()
– returns a ponter of hostent structure containing host
information corresponding to hname
• gethostbyaddr()
– returns a pointer of hostent structure based on in_addr, length,
address type arguments

• hostent structure
struct hostent {
char* h_name;
char** h_aliases;
int h_addrtype; // e.g., AF_INET=2
int h_length; // address length
char** h_addr_list; // list of addresses
};

#define h_addr h_addr_list[0] // first (or representative) address


get_hostent.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

int main(int argc, char *argv[]) {


struct hostent *hp;
struct in_addr in;
int i; char buf[20];

if(argc<2) {printf("Usage: %s hostname\n",argv[0]); exit(1);}


hp = gethostbyname(argv[1]);
if(hp==NULL) { printf("gethostbyname fail\n"); exit(0);}

printf(“host name : %s\n", hp->h_name);


printf(“host addr type : %d\n", hp->h_addrtype);
printf(“host addr length : %d byte\n", hp->h_length);
for( i=0; hp->h_addr_list[i]; i++) {
memcpy(&in.s_addr, hp->h_addr_list[i],sizeof(in.s_addr));
inet_ntop(AF_INET, &in, buf, sizeof(buf));
printf("IP address(%d th) : %s\n",i+1,buf);
}
for( i=0; hp->h_aliases[i]; i++)
printf(“host aliases (%d th) : %s ",i+1, hp->h_aliases[i]);
puts("");
return 0;
}
get_host_byaddr.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char *argv[]) {


struct hostent *myhost;
struct in_addr in;

if(argc < 2) {printf(“Usage : %s ip_address \n", argv[0]);exit(0);}

inet_pton(AF_INET, argv[1], &in.s_addr);// dotted decimal->32bit address


myhost = gethostbyaddr((char *)&(in.s_addr), sizeof(in.s_addr), AF_INET);

if (myhost == NULL) {
printf("Error at gethostbyaddr() \n");
exit(0);
}
printf(“host name : %s\n", myhost->h_name);
return 0;
}

You might also like