socket programming in c - eskisehir.edu.treem.eskisehir.edu.tr/isan/eem 482/icerik...3/28/2019 1...
TRANSCRIPT
3/28/2019
1
Socket Programming in CEEM482
Socket?• It defines an interface between application processes
• Socket: an object that allows reading/writing from a network interface• An Application Programming Interface (API) used for InterProcess
Communications
• Sockets bound to some IP and port number
• The socket library has various system calls• socket(), • bind(), • listen(), • connect(), • accept(),• send() / sendto(), • recv() / recvfrom, • close()
• In Unix, sockets are just file descriptors• read() and write() both work on sockets• Be careful: socket calls are blocking
3/28/2019
2
Client Server Paradigm
• One or more devices want to provide a service
• One or more devices want to use the service
• client-server architecture get them together
• Client :
• initiates contact with server (“speaks first”)• typically requests service from server,
• For Web apps, client is implemented in browser;
• Server:
• provides requested service to client
• e.g., Web server sends requested Web page.
Client
Server
Key Differences
• Execute on-demand
• Unprivileged
• Simple
• (Usually) sequential
• Not performance sensitive
• Always-on
• Privileged
• Complex
• (Massively) concurrent
• High performance
• Scalable
4
Clients Servers
3/28/2019
3
Types of Socket
• Two types of Internet Sockets• Stream sockets SOCK_STREAM
• Connection oriented
• Rely on TCP to provide reliable two-way connected communication
• Datagram sockets SOCK_DGRAM• Rely on UDP
• Connection is unreliable
Primary Socket Calls: socket()
• socket() : • Used by clients and servers• Gets a new socket• Returns a file descriptor(socket ID) if successful, -1 otherwise.
• Arguments• Domain: set to AF_INET• Type:
• SOCK_STREAM• SOCK_DGRAM
• Protocol: If it is set as zero, then socket will choose the correct protocol based on type or use IPPROTO_TCP / IPPROTO_UDP
int socket(int domain, int type, int protocol);
3/28/2019
4
Primary Socket Calls: bind()
• bind() : Associate a socket id to a network interface with an address and a port to which other processes can connect.
• Arguments• sockfd: It is the socket id
• my_addr: a pointer to the address family dependent address structure
• addrlen: It is the size of *my_addr
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
Primary Socket Calls: listen()
• listen() : Return 0 on success, or –1 if failure
• Arguments• sockfd: It is socket id created by socket()
• backlog : It is used to constraint the number of connection (set to 5 for tcp)
int listen(int sockfd, int backlog);
3/28/2019
5
Primary Socket Calls: connect()
• connect() : connect to a remote host
• Arguments• sockfd: It is the socket descriptor returned by socket()
• serv_addr : It is a pointer to struct sockaddr that contains information on destination IP address and port
• addrlen: It is set to sizeof(struct sockaddr)
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Primary Socket Calls: accept()
• accept() : gets the pending connection on the port you (server) are listen()ing on.
• Arguments• sockfd: It is the same socket id used by listen()
• addr: It is a pointer to a local struct sockaddr which stores the information about incoming connection
• addrlen: It is set to sizeof(struct sockaddr_in)
int accept(int sockfd, struct sockaddr *addr, int *addrlen);
3/28/2019
6
Primary Socket Calls: sendto()
• sendto() : Send a message. Returns the number of bytes sent or -1 if failure.
• Arguments• sockfd: It is the same socket id used by socket() or accept()• msg: It is the pointer to the data you want to send• fen: data length is sizeof(msg)• flags : It is set to be zero• dest_addr: It is a pointer to a local struct sockaddr which stores the information
about outgoing connection• addrlen: It is set to sizeof(struct sockaddr)
int sendto(int sockfd, const void *msg, int len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
Primary Socket Calls: recvfrom()
• recvfrom() : Receive up to len bytes in buf. Returns the number of bytes received or -1 on failure.
• Arguments• sockfd: It is the socket descriptor to read from• buf: It is the buffer to read the information info• len: It is the maximum length of the buffer• flags : It is set to be zero• src_addr: It is a pointer to a struct sockaddr which stores the information about
incoming connection• addrlen: It is set to sizeof(struct sockaddr)
int recv(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *src_addr, socklen_t *addrlen);
3/28/2019
7
Primary Socket Calls: close()
• Close() : Close connection corresponding to the socket descriptor and frees the socket descriptor.
• Arguments• sockfd: It is the socket descriptor to be closed
int close(int sockfd)
Port Numbers
14
• Basic mechanism for multiplexing applications per host• 65,535 ports available
• Why?
• Ports <1024 are reserved• Only privileged processes (e.g. superuser) may access
• Why?
• Does this cause security issues?
• “I tried to open a port and got an error”• Port collision: only one app per port per host
• Dangling sockets…
TCP/UDP port field is 16-bits wide
• Back in the day, all important apps used low port numbers
• Examples: IMAP, POP, HTTP, SSH, FTP• This rule is no longer useful
3/28/2019
8
Dangling Sockets
15
• Common error: bind fails with “already in use” error
• OS kernel keeps sockets alive in memory after close()• Usually a one minute timeout• Why?
• Allowing socket reuseint yes=1;
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt");
exit(1);
}
• Closing a TCP socket is a multi-step process• Involves contacting the remote machine• “Hey, this connection is closing”• Remote machine must acknowledge the closing• All this book keeping takes time
struct sockaddr
16
• Structure for storing naming information• But, different networks have different naming conventions
• Example: IPv4 (32-bit addresses) vs. IPv6 (64-bit addresses)
• In practice, use more specific structure implementation
1. struct sockaddr_in my_addr;
2. memset(&my_addr, 0, sizeof(sockaddr_in));
3. my_addr.sin_family = htons(AF_INET);
4. my_addr.sin_port = htons(MyAwesomePort);
5. my_addr.sin_addr.s_addr = inet_addr(«127.0.0.1");
3/28/2019
9
htons(), htonl(), ntohs(), ntohl()
17
• Little Endian vs. Big Endian• Not a big deal as long as data stays local
• What about when hosts communicate over networks?
• Network byte order• Standardized to Big Endian
• Be careful: x86 is Little Endian
• Functions for converting host order to network order• h to n s – host to network short (16 bits)
• h to n l – host to network long (32 bits)
• n to h * – the opposite
Shortcuts
18
• If you don’t care about the port• my_addr.sin_port = htons(0);
• Chooses a free port at random
• This is rarely the behavior you want for a server (but okay for clients)
• If you don’t care about the IP address• my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
• Meaning: don’t bind to a specific IP
• Traffic on any interface will reach the server• Assuming it’s on the right port
• This is usually the behavior you want for a server (but not clients)
3/28/2019
10
Programming with TCP Sockets in C –Client/Server Model• Applications that requires
• high reliability,• transmission time is less critical.
• Application Layer protocols like HTTP, HTTPs, FTP, SMTP, etc. use TCP.
• TCP also provides in order data packet delivery.• It successfully transmits data packets in the same order in which it is sent.
• TCP also provide Flow Control• TCP will also ensure that the sender does not overwhelm the destination by sending packets
faster than it can consume at the receiver side.
• TCP provides Congestion Control• It prevents congestion of a network.
• It also performs error checking and error recovery.• Erroneous packets are re-transmitted from the sender to the receiver.
Socket Programming for TCP• Server
1. using create(), Create TCP socket.2. using bind(), Bind the socket to
server address.3. using listen(), put the server
socket in a passive mode, where it waits for the client to approach the server to make a connection
4. using accept(), At this point, connection is established between client and server, and they are ready to transfer data.
5. Read/Write or Receive/Send Data between Client and Server
6. Go back to Step 3.
• Client1. Create TCP socket.2. Connect newly created client
socket to server.
3/28/2019
11
Server Side Operations
• Socket Creation and Verification in Server Side
• Bind the Socket to Server Address
• Listen to the Socket
• Accept Data Packet from Client
• Receive Data from Client connected in previous step
Socket Creation and Verification in Server Side
int serverSocket, connfd, len;
struct sockaddr_in server_address, client;
// socket creation and verification
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == -1) {
printf("Socket creation is failed.\n");
exit(0);
}
else
printf("Socket is successfully created.\n");
3/28/2019
12
Bind the Socket to Server Address
#define PORT 8080
bzero(&server_address, sizeof(server_address));
// assign IP address and a PORT number
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT);
// Binding the socket (serverSocket created before) to given IP and port and then verify
whether is binded
if ((bind(serverSocket, (struct sockaddr *)&server_address, sizeof(server_address))) != 0) {
printf(“Bind to socket is failed.\n");
exit(0);
} else
printf("Socket is successfully binded.\n");
Listen to the Socket
// Server is now ready to listen and verify it
if ((listen(serverSocket, 5)) != 0) {
printf("Listen is failed.\n");
exit(0);
} else
printf("Server is now listening.\n");
3/28/2019
13
Accept Data Packet from Client
len = sizeof(client);
// Accept data packets from client and verify it
connfd = accept(serverSocket, (struct sockaddr*)&client, &len);
if (connfd < 0) {
printf("Server acception is failed.\n");
exit(0);
} else
printf("Server acccepts the client.\n");
Read Client Data
#define MAX 100
// max 100 bytes of information can be received
char buff[MAX];
bzero(buff, MAX);
// read/receive the data from client and copy it in buffer (buf[])
read(serverSocket, buff, sizeof(buff));
// print the received buffer which contains the client data to the server screen
printf("From client: %s\t To client : ", buff);
3/28/2019
14
Client Side Operations
• Socket Creation and Verification in Client Side
• Connect to the Server Socket
• Write/Send Client Data to the Server Socket
• Close the socket
Socket Creation and Verification in Client Side
int clientSocket, connfd, len;
struct sockaddr_in server_address, client;
// socket creation and verification
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == -1) {
printf("Socket creation is failed.\n");
exit(0);
}
else
printf("Socket is successfully created.\n");
3/28/2019
15
Connect to the Server Socket
#define PORT 8080
bzero(&server_address, sizeof(server_address));
// assign IP address and a PORT number
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(PORT);
// connect the client socket to the server socket
if (connect(clientSocket, (struct sockaddr*)&server_address, sizeof(server_address)) != 0) {
printf(“Connection with the server is failed.\n");
exit(0);
} else
printf(“Connection with the server is successful.\n");
Write/Send Client Data to the Server Socket
#define MAX 100
// max 100 bytes of information can be received
char buff[MAX]=“Hello there, I am the Client”;
// Write/send the data from client to the server
write(clientSocket, buff, sizeof(buff));
3/28/2019
16
Close the Client/Server Socket
• Client// close the client socket with its file descriptor
close(clientSocket);
• Server// close the server socket with its file descriptor
close(serverSocket);
Programming with UDP Sockets in C –Client/Server Model• Applications for
• requiring low-latency,• loss-tolerating connections.
• Application Layer protocols• Domain Name System (DNS)• Streaming media applications IPTV• Trivial File Transfer Protocol (TFTP)• Voice over IP (VoIP)• Real-Time Games• Multiplayer Games
• some frames lost is OK but lag in the game is bad for gamer experience.
• There is no reliability of data being exchanged
• If the speed is concerned and data loss is tolerable, then UDP is the best candidate.
3/28/2019
17
Socket Programming for UDP• Server
1. Create UDP socket.2. Bind the socket to server
address.3. Wait until datagram packet
arrives from client.4. Process the datagram packet and
send a reply to client.5. Go back to Step 3.
• Client1. Create UDP socket.2. Send message to server.3. Wait until response from server
is recieved.4. Process reply and go back to step
2, if necessary.5. Close socket descriptor and exit.
Server Side Operations
• Socket Creation and Verification in Server Side
• Bind the Socket to Server Address
• Wait until Datagram Packet from Client is received
• Process the Datagram Packet and Send Reply to the Client
3/28/2019
18
Socket Creation and Verification in Server Side
int serverSocket;
struct sockaddr_in server_address, client_address;
// socket creation and verification
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serverSocket == -1) {
printf("Socket creation is failed.\n");
exit(0);
}
else
printf("Socket is successfully created.\n");
Bind the Socket to Server Address
#define PORT 8080
bzero(&server_address, sizeof(server_address));
// assign IP address and a PORT number
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT);
// Binding the socket (serverSocket created with the server address before) to given IP and
port and then verify whether is binded
if ((bind(serverSocket, (struct sockaddr *)&server_address, sizeof(server_address))) != 0) {
printf(“Bind to socket is failed.\n");
exit(0);
} else
printf("Socket is successfully binded.\n");
3/28/2019
19
Wait until Datagram Packet from Client is received
int len, n;
// wait to receive data from client
n = recvfrom(serverSocket, (char *)buff,
MAXLINE, MSG_WAITALL,
(struct sockaddr *)&client_address, &len);
buff[n] = '\0’;
printf(“Data received from Client : %s\n", buffer);
// MSG_WAITALL flag requests that the operation block until the full request is satisfied.
Process the Datagram Packet and Send Reply to the Client
// process the datagram received from client
Do something on buff[]
// send reply to the client
char *serverData = "I am the server, received your data and performed some operations";
sendto(serverSocket, (const char *)serverData,
strlen(serverData), MSG_CONFIRM,
(const struct sockaddr *)&client_address, len);
printf(“Server data is sent.\n");
3/28/2019
20
Client Side Operations
• Socket Creation and Verification in Client Side
• Send Data to the Server
• Wait until response message from server is received
• Process the received packet and go back to sending data step, if necessary.
• Close client socket file descriptor and exit.
Socket Creation and Verification in Client Side
int clientSocket;
struct sockaddr_in server_address;
// socket creation and verification
clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (clientSocket == -1) {
printf("Socket creation is failed.\n");
exit(0);
}
else
printf("Socket is successfully created.\n");
3/28/2019
21
Send Data to the Server
#define PORT 8080
bzero(&server_address, sizeof(server_address));
// assign IP address and a PORT number
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(PORT);
char *clientData = "I am the client, this is my data";
sendto(clientSocket, (const char *)clientData, strlen(clientData),
MSG_CONFIRM, (const struct sockaddr *)& server_address,sizeof(server_address));
printf(“Client data is sent.\n");
Wait until response message from server is received
#define MAX 100
int len, n;
char buff[MAX];
// wait to receive data from client
n = recvfrom(clientSocket, (char *)buff,
MAX, MSG_WAITALL,
(struct sockaddr *)&client_address, &len);
buff[n] = '\0’;
printf(“Data received from Client : %s\n", buffer);
// MSG_WAITALL flag requests that the operation block until the full request is satisfied.
3/28/2019
22
Process the received packet and close the socket
// printing the received packet on the screen
buff[n] = '\0’;
printf(“Data received from Client : %s\n", buff);
• Client// close the client socket with its file descriptor
close(clientSocket);
return 0;
Common Arguments in the Socket Functions
• AF_INET for IPv4/ AF_INET6 for IPv6• SOCK_STREAM for TCP / SOCK_DGRAM for UDP• IPPROTO_UDP for TCP / IPPROTO_UDP for UDP
• serverSocket – File descriptor of socket • clientSocket – File descriptor of socket
• buff – Application buffer containing the data to be sent/received• len – Size of buff, application buffer• server_address – Structure containing address of destination• sizeof(server_address) – Size of server_address structure