Piotr Mielecki Ph. D.

Similar documents
UNIX Network Programming. Overview of Socket API Network Programming Basics

CS307 Operating Systems Processes

Processes. Process Concept. The Process. The Process (Cont.) Process Control Block (PCB) Process State

Network Programming Worksheet 2. Simple TCP Clients and Servers on *nix with C.

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

Introduction to Client-Server Model

Unix Network Programming Chapter 4. Elementary TCP Sockets 광운대학교컴퓨터과학과 정보통신연구실 석사과정안중현

Hyo-bong Son Computer Systems Laboratory Sungkyunkwan University

Sockets. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

PA #2 Reviews. set_name, get_name, del_name. Questions? Will be modified after PA #4 ~

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

CS 3516: Computer Networks

CS321: Computer Networks Socket Programming

Lecture 3 Overview! Last Lecture! TCP/UDP and Sockets introduction!

ECE 435 Network Engineering Lecture 2

CS321: Computer Networks Introduction to Application Layer

Experiential Learning Workshop on Basics of Socket Programming

The BSD UNIX Socket Interface (CS 640 Lecture) Assignment 1. Interprocess Communication (IPC) Work Individually (no groups)

NETWORK AND SYSTEM PROGRAMMING. I/O Multiplexing: select and poll function

ECE 435 Network Engineering Lecture 2

Elementary TCP Sockets

Embedded System Design

CS4514 B08 HELP Session 1

ECE322 Systems Programming Project 2: Networking with Matrix Multiplication in C Grant Kimes 12/16/15

Application Programming Interfaces

Inter-Process Communication. Disclaimer: some slides are adopted from the book authors slides with permission 1

CSE 333 SECTION 8. Sockets, Network Programming

CSE 333 SECTION 7. C++ Virtual Functions and Client-Side Network Programming

Data and Computer Communications. Tenth Edition by William Stallings

Introduction to Socket Programming

CSE 333 SECTION 7. Client-Side Network Programming

Semester 2, Computer Communication 352 Module 4

Week 2 Intro to the Shell with Fork, Exec, Wait. Sarah Diesburg Operating Systems CS 3430

Network Socket Programming - 3 BUPT/QMUL

Processes communicating. Network Communication. Sockets. Addressing processes 4/15/2013

CS 471 Operating Systems. Spring 2016 Midterm Exam Time 2 & 1/2 hours. Open Book & Notes

CS4700/CS5700 Fundamentals of Computer Networking

Network Socket Programming - 3 BUPT/QMUL

Applications and Layered Architectures. Chapter 2 Communication Networks Leon-Garcia, Widjaja

How do we Communicate? Introduction to Unix Network Programming. What does Alice do? What does Bob do? Two simplest networking programs

NETWORK PROGRAMMING. Instructor: Junaid Tariq, Lecturer, Department of Computer Science

Review. Preview. Closing a TCP Connection. Closing a TCP Connection. Port Numbers 11/27/2017. Packet Exchange for TCP Connection

1 /* client.c - adapted from code for example client program that uses TCP */ 2 /*Modified by Vincent Chu, Winter

Internet protocol stack. Internetworking II: Network programming. April 20, UDP vs TCP. Berkeley Sockets Interface.

Internetworking II: Network programming. April 20, 2000

Client/Server. Networking Approach.

Unix Network Programming

Network Communication

The Berkeley Sockets API. Networked Systems Architecture 3 Lecture 4

Socket Programming. CSIS0234A Computer and Communication Networks. Socket Programming in C

04 Elementary. Client/Server. CEN 463 Network Programming. Dr. Mostafa Hassan Dahshan. King Saud University

Introduction to Socket Programming

Java Basics 5 - Sockets. Manuel Oriol - May 4th, 2006

CSE 333 SECTION 6. Networking and sockets

Network Programming in C: The Berkeley Sockets API. Networked Systems 3 Laboratory Sessions

Message passing systems are popular because they support client-server interactions, where: clients send messages to servers requesting a server.

TCP/IP Sockets in C: Practical Guide for Programmers. Computer Chat. Internet Protocol (IP) IP Address. Transport Protocols. Ports

CS 640: Computer Networking

MSc Integrated Electronics Networks Assignment. Investigation of TCP/IP Sockets and Ports. Gavin Cameron

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2018 Lecture 20

A GENERALIZED FRAMEWORK FOR CATV TRANSMISSION ON FUTURE BISDN

Linux Network Programming, Part 1

INTEGRATED INFORMATION AND COMMUNICATION LEARNING MODEL FOR RASPBERRY Pi ENVIRONMENT

Lab 0. Yvan Petillot. Networks - Lab 0 1

Introduction and Overview Socket Programming Higher-level interfaces Final thoughts. Network Programming. Samuli Sorvakko/Nixu Oy

Network Programming in C. Networked Systems 3 Laboratory Sessions and Problem Sets

ICT 6544 Distributed Systems Lecture 5

Azblink API for Sending XMPP Messages via HTTP POST

Interprocess Communication Mechanisms

Programming with TCP/IP. Ram Dantu

Unix-Linux 2. Unix is supposed to leave room in the process table for a superuser process that could be used to kill errant processes.

CSC Systems Programming Fall Lecture - XV Network Programming - I. Tevfik Ko!ar. Louisiana State University. November 9 th, 2010

Lecture 7. Followup. Review. Communication Interface. Socket Communication. Client-Server Model. Socket Programming January 28, 2005

CSE 333 Lecture 16 - network programming intro

Network programming(i) Lenuta Alboaie

Client-server model The course that gives CMU its Zip! Network programming Nov 27, Using ports to identify services.

CS118 Discussion 1B, Week 1. Taqi Raza BUNCHE 1209B, Fridays 12:00pm to 1:50pm

Chapter 5. TCP Client-Server

Interprocess Communication Mechanisms

/* * porting from BSD to SVR4 */ #ifdef USE_BSD # include <machine/param.h> #endif

CS240: Programming in C

Operating Systems, laboratory exercises. List 2.

A Socket Example. Haris Andrianakis & Angelos Stavrou George Mason University

Introduction and Overview Socket Programming Higher-level interfaces Final thoughts. Network Programming. Samuli Sorvakko/Nixu Oy

System Programming. Process Control II

Announcement (1) Due date for PA3 is changed (~ next week) PA4 will also be started in the next class. Not submitted. Not scored

Introduction and Overview Socket Programming Lower-level stuff Higher-level interfaces Security. Network Programming. Samuli Sorvakko/Nixu Oy

Client software design

How to write a Measurement Telnet Server

CSE 421/521 - Operating Systems Fall 2011 Recitations. Recitation - III Networking & Concurrent Programming Prof. Tevfik Kosar. Presented by...

CompSci 356: Computer Network Architectures Lecture 3: Hardware and physical links References: Chap 1.4, 1.5 of [PD] Xiaowei Yang

System Programming. Sockets: examples

CS240: Programming in C

Operating systems and concurrency - B03

Prepared by Prof. Hui Jiang Process. Prof. Hui Jiang Dept of Electrical Engineering and Computer Science, York University

Cracking WEP Keys Using WEPCrack

Process. Prepared by Prof. Hui Jiang Dept. of EECS, York Univ. 1. Process in Memory (I) PROCESS. Process. How OS manages CPU usage? No.

CompSci 356: Computer Network Architectures. Lecture 3: Network Architecture Examples and Lab 1. Xiaowei Yang

Ά η η 1 (30%): Sockets. socket () bind () listen () accept () connect () read () write () close ()

Why a Computer Network??? Stand alone Computer. For What?

Transcription:

Piotr Mielecki Ph. D. http://mielecki.ristel.pl/ piotr.mielecki@pwr.edu.pl pmielecki@gmail.com

Building blocks of client-server applications: Client, Server, Middleware. Simple client-server application: Version 1.0 non-multitasking server, client s requests queued and serviced according to FIFO strategy. Version 2.0 multitasking server, client s requests are serviced parallel. Version 2.5 multitasking server which can be installed as UNIX / Linux system service (daemon).

Client: runs the client side of the application, runs on the OS that provides an user interface and that can access distributed services, wherever they may be, the client can also run a component of the Distributed System Management (DSM) element: DSM agents run on every node in the client/server network, managing workstation collects information from all its agents on the network and displays it, the managing workstation can also instruct its agents to perform actions on its behalf.

Server: runs the server side of the application, the server application typically runs on top of some shrink-wrapped server software package, the five contending server platforms for creating client/server applications are: SQL database severs, Transaction Processing Monitors to ensure that the transaction processes completely or, if an error occurs, to take appropriate actions (in most of cases integrated with database servers), groupware servers, object servers see Component Object Model (COM) for example, web servers, the server side depends on the OS to interface with the middleware building block, it may be a simple agent or a shared object database etc.

Middleware: runs on both the client and server sides of an application, middleware is the nervous system of the client/server infrastructure, this can also have the Distributed System Management (DSM) component.

Client Middleware Server User interface Web browser DSM OS Service specific HTTP ODBC Mail TxRPC ORB Distributed System Management (DSM) SNMP CMIP Tivoli / ORB Network Operating System (NOS) Directory Services Security Distributed File System RPC Messaging Peer-to-Peer Transport stack NetBIOS TCP/IP IPX/SPX SNA SQL DBMS TP Monitor Groupware Objects Web server DSM OS

Server waits for message from client and sends back acknowledgement after receiving. Client sends message to server and waits for acknowledgement. Both use UNIX TCP/IP sockets as middleware. When server receives SHUTDOWN message quits (server recognizes a command from client we can call it Application level protocol ). Message Acknowledgement Sends a text message to server Waits for message from client

Server program (v. 1.0): Create socket Listen on socket NO Connection requested YES Receive message Send acknowledgement Accept connection Provide service Close connection Close socket YES SHUTDOWN command NO Quit

Server v. 1.0 code, part 1: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int sockfd, consockfd; // Socket file descriptors struct sockaddr_in serv_addr, cli_addr; socklen_t clilen; char cli_addr_str[inet_addrstrlen]; char buffer[buff_len]; const char *ack_message = "Message acknowledged."; int n; if (argc < 3) // Server s IP and port given in command line fprintf(stderr,"command: %s <address> <port>\n", argv[0]); clilen = sizeof(cli_addr); // Set length of client address

Server v. 1.0 code, part 2: // Step 1. Create the Internet socket (SOCK_STREAM and 0 means TCP): sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"server ERROR: socket opening failed.\n"); // Initialize address of the server in serv_addr: bzero( (char *) &serv_addr, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; // Function inet_pton() gets IP address from C character string and // stores it in sin_addr field of sockaddr_in type structure. // Use this function rather instead obsolete inet_addr() which doesn't // support IPv6. In this example AF_INET means IPv4. inet_pton( AF_INET, argv[1], &(serv_addr.sin_addr) ); // Function htons() converts port number in host byte order // (depends on host computer architecture) to a port number // in network byte order (standardized). serv_addr.sin_port = htons( atoi(argv[2]) );

Server v. 1.0 code, part 3: // Step 2. Bind the socket to address - sets the value of file // descriptor (handle). // Typecasting is required to fit sockaddr_in type structure // to general sockaddr type. if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) fprintf(stderr,"server ERROR: binding failed, the port is in use.\n"); // Step 3. Listen on socket pointed by its handle. // The 2nd parameter is size of the backlog queue - the number // of connections that can be waiting while the process is handling // a particular connection. Typicaly 5 is the maximum value. listen( sockfd, 5 );

Server v. 1.0 code, part 4: // Step 4. Accept connections from clients and perform operations. do // Function accept() blocks process till any connection from // client comes. consockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen ); // The returned new handle to socket represents this particular // connection and should be used for servicing this connection. if (consockfd < 0) fprintf(stderr,"server ERROR: accept failed.\n"); // Function inet_ntop() gets address from sin_addr field of sockaddr_in // type structure and stores it to C character string. inet_ntop(af_inet, &(cli_addr.sin_addr), cli_addr_str, INET_ADDRSTRLEN); printf("[server] Connection accepted with client %s port %d\n", cli_addr_str, ntohs(cli_addr.sin_port));

Server v. 1.0 code, part 5: bzero( buffer, BUFF_LEN ); n = read( consockfd, buffer, BUFF_LEN ); // Read from the socket. if (n < 0) fprintf(stderr,"server ERROR: reading from socket failed.\n"); printf("[server] Message from client: Length = %d Content = %s\n", strlen(buffer), buffer); // Send acknowledgement message write to socket: n = write( consockfd, ack_message, strlen(ack_message) ); if (n < 0) fprintf(stderr,"server ERROR: writing to socket failed.\n"); close( consockfd ); // Close socket descriptor used by connection. while ( strcmp( buffer, "SHUTDOWN" )!= 0 ); // Until SHUTDOWN command

Server v. 1.0 code, part 6: // Exiting the server program: close( sockfd ); // Close socket descriptor used for listening. printf("[server] - Shutting down.\n"); return 0;

Client program (v. 1.0): Create socket Connect to server Send message Receive acknowledgement Close socket Quit

Client v. 1.0 code, part 1: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int sockfd, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[buff_len]; if (argc < 3) // Server s IP address and port given in command line. fprintf(stderr,"command: %s <address> <port>\n", argv[0]);

Client v. 1.0 code, part 2: // Step 1. Get host address for IP or URL given in argv[1]: server = gethostbyname( argv[1] ); if (server == NULL) fprintf(stderr,"error: server host not found.\n"); // Step 2. Create server address from gethostbyname() result: bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy( (char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length ); serv_addr.sin_port = htons( atoi(argv[2]) ); // Step 3. Create the Internet socket (SOCK_STREAM and 0 means TCP): sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"error: socket opening failed.\n");

Client v. 1.0 code, part 3: // Step 4. Connect to server - operation compatible with accept() // on server side: if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) fprintf(stderr,"error: connecting to server failed.\n"); // Input message text to the buffer: bzero( buffer, BUFF_LEN ); printf("message FOR server: "); fgets( buffer, BUFF_LEN, stdin ); // Replace end of line character(s) with NULL terminator: for( n = 0; n < strlen(buffer); n++ ) if ( buffer[n] == '\n' buffer[n] == '\r' ) buffer[n] = '\0';

Client v. 1.0 code, part 4: // Step 5. Send the message to server via socket: n = write( sockfd, buffer, strlen(buffer) ); if (n < 0) fprintf(stderr,"error: writing to socket failed.\n"); // Step 6. Read acknowledge message from server via socket: bzero( buffer, BUFF_LEN ); n = read( sockfd, buffer, BUFF_LEN ); if (n < 0) fprintf(stderr,"error: reading from socket failed.\n"); printf( "Message FROM server: %s\n", buffer ); // Step 7. Close Internet socket and connection: close( sockfd ); return 0;

Client program (v. 1.5): Create socket Connect to server Send message Receive acknowledgement Close socket YES QUIT command NO Quit YES SHUTDOWN command NO

Client v. 1.5 code, part 1: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int sockfd, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[buff_len]; if (argc < 3) // Server s IP address and port given in command line. fprintf(stderr,"command: %s <address> <port>\n", argv[0]);

Client v. 1.5 code, part 2: // Step 1. Get host address for IP or URL given in argv[1]: server = gethostbyname( argv[1] ); if (server == NULL) fprintf(stderr,"error: server host not found.\n"); // Step 2. Create server address from gethostbyname() result: bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy( (char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length ); serv_addr.sin_port = htons( atoi(argv[2]) ); do // Client loop begining (doesn t exist in v. 1.0). // Step 3. Create the Internet socket: sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"error: socket opening failed.\n");

Client v. 1.5 code, part 3: // Step 4. Connect to server - operation compatible with accept() // on server side: if (connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) fprintf(stderr,"error: connecting to server failed.\n"); // Input message text to the buffer: bzero( buffer, BUFF_LEN ); printf("message FOR server: "); fgets( buffer, BUFF_LEN, stdin ); // Replace end of line character(s) with NULL terminator: for( n = 0; n < strlen(buffer); n++ ) if ( buffer[n] == '\n' buffer[n] == '\r' ) buffer[n] = '\0'; // Check the exit conditions (doesn t exist in v. 1.0): if ( strcmp(buffer, "QUIT") == 0 strcmp(buffer, "SHUTDOWN") == 0 ) next_msg = 0; else next_msg = 1;

Client v. 1.5 code, part 4: // Step 5. Send the message to server via socket: n = write( sockfd, buffer, strlen(buffer) ); if (n < 0) fprintf(stderr,"error: writing to socket failed.\n"); // Step 6. Read acknowledge message from server via socket: bzero( buffer, BUFF_LEN ); n = read( sockfd, buffer, BUFF_LEN ); if (n < 0) fprintf(stderr,"error: reading from socket failed.\n"); printf( "Message FROM server: %s\n", buffer ); // Step 7. Close Internet socket and connection: close( sockfd ); while ( next_msg!= 0 ); // Client loop end. printf( "Quiting.\n" ); return 0;

Server program (v. 2.0): Create socket NO Listen on socket Connection requested PARENT fork() YES CHILD Accept connection Close connection Perform service 1 Exit child process NO QUIT command YES Close socket Close connection Quit parent process YES SHUTDOWN command NO 1 Exit child process

Server v. 2.0 code, part 1: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/wait.h> #include <signal.h> #define BUFF_LEN 256 // Length of the message buffer. int sockfd; // Parent socket handle declared as public // to be available for SIGQUIT handler.

Server v. 2.0 code, part 2: // Handler for SIGCHLD signal raised up by each child process on exit. // Parent process reads all information about exiting child to avoid // zombie creation. void sigchld_handler( int signo ) pid_t PID; int status; do PID = waitpid( -1, &status, WNOHANG ); while ( PID!= -1 ); signal( SIGCHLD, sigchld_handler ); // Handler for SIGQUIT signal used to quit parent process. void sigquit_handler( int signo ) close( sockfd ); printf("[server] Shutting down.\n"); exit( 0 );

Server v. 2.0 code, part 3: #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int consockfd; struct sockaddr_in serv_addr, cli_addr; socklen_t clilen; char cli_addr_str[inet_addrstrlen]; unsigned short cli_port; char buffer[buff_len]; const char *ack_message = "Message acknowledged."; pid_t PID, PPID; int n; if (argc < 3) fprintf(stderr,"command: %s <address> <port>\n", argv[0]); signal( SIGCHLD, sigchld_handler ); clilen = sizeof(cli_addr); // Set SIGCHLD signal handler.

Server v. 2.0 code, part 4: // Step 1. Create the Internet socket (SOCK_STREAM and 0 means TCP): sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"server ERROR: socket opening failed.\n"); // Initialize address of the server in serv_addr: bzero( (char *) &serv_addr, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; // Function inet_pton() gets IP address from C character string and // stores it in sin_addr field of sockaddr_in type structure. // Use this function rather instead obsolete inet_addr() which doesn't // support IPv6. In this example AF_INET means IPv4. inet_pton( AF_INET, argv[1], &(serv_addr.sin_addr) ); // Function htons() converts port number in host byte order // (depends on host computer architecture) to a port number // in network byte order (standardized). serv_addr.sin_port = htons( atoi(argv[2]) );

Server v. 2.0 code, part 5: // Step 2. Bind the socket to address - sets the value of file // descriptor (handle). // Typecasting is required to fit sockaddr_in type structure // to general sockaddr type. if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) fprintf(stderr,"server ERROR: binding failed, the port is in use.\n"); // Step 3. Listen on socket pointed by its handle. // The 2nd parameter is size of the backlog queue - the number // of connections that can be waiting while the process is handling // a particular connection. Typicaly 5 is the maximum value. listen( sockfd, 5 );

Server v. 2.0 code, part 6: // Step 4. Accept connections from clients and perform operations. do // Server main loop begining. consockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen ); if (consockfd < 0) fprintf(stderr,"server ERROR: accept failed.\n"); inet_ntop(af_inet, &(cli_addr.sin_addr), cli_addr_str, INET_ADDRSTRLEN); printf("[server] Connection accepted with client %s port %d\n", cli_addr_str, ntohs(cli_addr.sin_port)); // Create child process for servicing client s request: if( (PID = fork()) == -1 ) // fork() error. close( consockfd ); fprintf(stderr,"server ERROR: Creating new process failed.\n"); continue; else if( PID > 0 ) // Parent process. close( consockfd ); // Close the parent's copy of handle. signal( SIGQUIT, sigquit_handler ); // Set SIGQUIT signal handler. continue;

Server v. 2.0 code, part 7: // Child process starts here. PPID = getppid(); do // Session loop session with client. bzero( buffer, BUFF_LEN ); n = read( consockfd, buffer, BUFF_LEN ); // Read message from client. if (n < 0) fprintf(stderr,"server ERROR: reading from socket failed.\n"); // Replace end of line character(s) with terminator: for( n = 0; n < strlen(buffer); n++ ) if ( buffer[n] == '\n' buffer[n] == '\r' ) buffer[n] = '\0'; printf("[server] Message from client [%s %d]: %s\n", cli_addr_str, cli_port, buffer); n = write( consockfd, ack_message, strlen(ack_message) ); if (n < 0) fprintf(stderr,"server ERROR: writing to socket failed.\n");

Server v. 2.0 code, part 8: if ( strcmp(buffer, "SHUTDOWN") == 0 ) printf("[server] Shutting down.\n"); kill( PPID, SIGQUIT ); // Send SIGQUIT signal to parent process. break; while ( strcmp( buffer, "QUIT" )!= 0 ); // Session loop end. printf("[server] Session with client [%s %d] quits.\n", cli_addr_str, cli_port); close( consockfd ); exit( 0 ); // Exit child process (session with client). while ( 1 ); // Server main loop end.

Client program (v. 2.0): Create socket Connect to server Send message Receive acknowledgement YES QUIT command NO Close socket YES SHUTDOWN command NO Quit

Client v. 2.0 code, part 1: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int sockfd, n, next_msg; struct sockaddr_in serv_addr; struct hostent *server; char buffer[buff_len]; if (argc < 3) fprintf(stderr,"command: %s <address> <port>\n", argv[0]);

Client v. 2.0 code, part 2: // Step 1. Get host address for IP or URL given in argv[1]: server = gethostbyname( argv[1] ); if (server == NULL) fprintf(stderr,"error: server host not found.\n"); // Step 2. Create server address from gethostbyname() result: bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy( (char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length ); serv_addr.sin_port = htons( atoi(argv[2]) ); // Step 3. Create the Internet socket: sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"error: socket opening failed.\n");

Client v. 2.0 code, part 3: // Step 4. Connect to server - operation compatible with accept() // on server side: if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) fprintf(stderr,"error: connecting to server failed.\n"); do // Client main loop session with active TCP connection. // Input message text to the buffer. bzero( buffer, BUFF_LEN ); printf("message FOR server: "); fgets( buffer, BUFF_LEN, stdin ); // Replace end of line character(s) with terminator: for( n = 0; n < strlen(buffer); n++ ) if ( buffer[n] == '\n' buffer[n] == '\r' ) buffer[n] = '\0'; // Check the exit conditions: if ( strcmp(buffer, "QUIT") == 0 strcmp(buffer, "SHUTDOWN") == 0 ) next_msg = 0; else next_msg = 1;

Client v. 2.0 code, part 4: // Step 5. Send the message to server via socket: n = write( sockfd, buffer, strlen(buffer) ); if (n < 0) fprintf(stderr,"error: writing to socket failed.\n"); // Step 6. Read acknowledge message from server via socket: bzero( buffer, BUFF_LEN ); n = read( sockfd, buffer, BUFF_LEN ); if (n < 0) fprintf(stderr,"error: reading from socket failed.\n"); printf( "Message FROM server: %s\n", buffer ); while ( next_msg!= 0 ); printf( "Quiting.\n" ); // Step 7. Close Internet socket and connection (session): close( sockfd ); return 0;

Server v. 2.5 (daemon) code, part 1: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/wait.h> #include <signal.h> #define BUFF_LEN 256 // Length of the message buffer. int sockfd; // Parent socket handle declared as public // to be available for SIGQUIT handler.

Server v. 2.5 code, part 2: // Handler for SIGCHLD signal raised up by each child process on exit. // Parent process reads all information about exiting child to avoid // zombie creation. void sigchld_handler( int signo ) pid_t PID; int status; do PID = waitpid( -1, &status, WNOHANG ); while ( PID!= -1 ); signal( SIGCHLD, sigchld_handler ); // Handler for SIGQUIT signal used to quit parent process. void sigquit_handler( int signo ) close( sockfd ); printf("[server] Shutting down.\n"); exit( 0 );

Server v. 2.5 code, part 3: #define BUFF_LEN 256 // Length of the message buffer int main(int argc, char *argv[]) int consockfd; struct sockaddr_in serv_addr, cli_addr; socklen_t clilen; char cli_addr_str[inet_addrstrlen]; unsigned short cli_port; char buffer[buff_len]; const char *ack_message = "Message acknowledged."; pid_t PID, PPID; int n; if (argc < 3) fprintf(stderr,"command: %s <address> <port>\n", argv[0]);

Server v. 2.5 code, part 4: // Function daemon() "cuts-off" the process from its parent, // that means process becomes intentionaly created orphan // and can run without user's session. // In fact it's a kind of fork() which kills parent process. // // Prototype: int daemon(int nochdir, int noclose); // nochdir - if set to 0 process changes its working // directory to / // noclose - if set to 0 process redirects standard input, // standard output and standard error to /dev/null daemon( 0, 1 ); signal( SIGCHLD, sigchld_handler ); // Set SIGCHLD signal handler. clilen = sizeof(cli_addr);

Server v. 2.5 code, part 5: // Step 1. Create the Internet socket (SOCK_STREAM and 0 means TCP): sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) fprintf(stderr,"server ERROR: socket opening failed.\n"); // Initialize address of the server in serv_addr: bzero( (char *) &serv_addr, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; // Function inet_pton() gets IP address from C character string and // stores it in sin_addr field of sockaddr_in type structure. // Use this function rather instead obsolete inet_addr() which doesn't // support IPv6. In this example AF_INET means IPv4. inet_pton( AF_INET, argv[1], &(serv_addr.sin_addr) ); // Function htons() converts port number in host byte order // (depends on host computer architecture) to a port number // in network byte order (standardized). serv_addr.sin_port = htons( atoi(argv[2]) );

Server v. 2.5 code, part 6: // Step 2. Bind the socket to address - sets the value of file // descriptor (handle). // Typecasting is required to fit sockaddr_in type structure // to general sockaddr type. if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) fprintf(stderr,"server ERROR: binding failed, the port is in use.\n"); // Step 3. Listen on socket pointed by its handle. // The 2nd parameter is size of the backlog queue - the number // of connections that can be waiting while the process is handling // a particular connection. Typicaly 5 is the maximum value. listen( sockfd, 5 );

Server v. 2.5 code, part 7: // Step 4. Accept connections from clients and perform operations. do // Server main loop begining. consockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen ); if (consockfd < 0) fprintf(stderr,"server ERROR: accept failed.\n"); inet_ntop(af_inet, &(cli_addr.sin_addr), cli_addr_str, INET_ADDRSTRLEN); printf("[server] Connection accepted with client %s port %d\n", cli_addr_str, ntohs(cli_addr.sin_port)); // Create child process for servicing client s request: if( (PID = fork()) == -1 ) // fork() error. close( consockfd ); fprintf(stderr,"server ERROR: Creating new process failed.\n"); continue; else if( PID > 0 ) // Parent process. close( consockfd ); // Close the parent's copy of handle. signal( SIGQUIT, sigquit_handler ); // Set SIGQUIT signal handler. continue;

Server v. 2.5 code, part 8: // Child process starts here. PPID = getppid(); do // Session loop session with client. bzero( buffer, BUFF_LEN ); n = read( consockfd, buffer, BUFF_LEN ); // Read message from client. if (n < 0) fprintf(stderr,"server ERROR: reading from socket failed.\n"); // Replace end of line character(s) with terminator: for( n = 0; n < strlen(buffer); n++ ) if ( buffer[n] == '\n' buffer[n] == '\r' ) buffer[n] = '\0'; printf("[server] Message from client [%s %d]: %s\n", cli_addr_str, cli_port, buffer); n = write( consockfd, ack_message, strlen(ack_message) ); if (n < 0) fprintf(stderr,"server ERROR: writing to socket failed.\n");

Server v. 2.5 code, part 9: if ( strcmp(buffer, "SHUTDOWN") == 0 ) printf("[server] Shutting down.\n"); kill( PPID, SIGQUIT ); // Send SIGQUIT signal to parent process. break; while ( strcmp( buffer, "QUIT" )!= 0 ); // Session loop end. printf("[server] Session with client [%s %d] quits.\n", cli_addr_str, cli_port); close( consockfd ); exit( 0 ); // Exit child process (session with client). while ( 1 ); // Server main loop end.