Simple network applications using sockets (BSD and WinSock) Revision 1 Copyright Clifford Slocombe

Similar documents
CSCE 463/612 Networks and Distributed Processing Spring 2017

WinSock. What Is Sockets What Is Windows Sockets What Are Its Benefits Architecture of Windows Sockets Network Application Mechanics

Socket Programming for TCP and UDP

Hybrid of client-server and P2P. Pure P2P Architecture. App-layer Protocols. Communicating Processes. Transport Service Requirements

CS321: Computer Networks Introduction to Application Layer

Lecture 24. Thursday, November 19 CS 375 UNIX System Programming - Lecture 24 1

Socket Programming. Sungkyunkwan University. Hyunseung Choo Copyright Networking Laboratory

A Client-Server Exchange

Ports under 1024 are often considered special, and usually require special OS privileges to use.

2007 Microsoft Corporation. All rights reserved.

CS321: Computer Networks Socket Programming

Linux Network Programming, Part 1

ECE 435 Network Engineering Lecture 2

Oral. Total. Dated Sign (2) (5) (3) (2)

A. Basic Function Calls for Network Communications

Computer Network Lab, SS Fachgebiet Technische Informatik, Joachim Zumbrägel. Overview. Sockets. Sockets in C.

Hyo-bong Son Computer Systems Laboratory Sungkyunkwan University

Client Server Computing

Context. Distributed Systems: Sockets Programming. Alberto Bosio, Associate Professor UM Microelectronic Departement

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

Introduction to Computer Networks

What s an API? Do we need standardization?

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

Tutorial on Socket Programming

31 ChamSys Remote Protocol Commands

How to write a Measurement Telnet Server

EECS122 Communications Networks Socket Programming. Jörn Altmann

Unix Network Programming

ECE 435 Network Engineering Lecture 2

Windows Sockets: A Quick And Dirty Primer

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

CS 3516: Computer Networks

Socket Programming TCP UDP

CS 640: Computer Networking

Socket Programming. Dr. -Ing. Abdalkarim Awad. Informatik 7 Rechnernetze und Kommunikationssysteme

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

Elementary TCP Sockets

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

Socket Programming 2007/03/28

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

SOCKETS. COMP750 Distributed Systems

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

Winsock Server adding Multiple clients support C++

Network Software Implementations

Session NM056. Programming TCP/IP with Sockets. Geoff Bryant Process software

ELEC / COMP 177 Fall Some slides from Kurose and Ross, Computer Networking, 5 th Edition

UNIX Network Programming. Overview of Socket API Network Programming Basics

Networked Applications: Sockets. End System: Computer on the Net

EECS 123: Introduction to Real-Time Distributed Programming

Sockets. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Programming with TCP/IP. Ram Dantu

Network Socket Programming - 3 BUPT/QMUL

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

Lab 0. Yvan Petillot. Networks - Lab 0 1

Socket Programming. #In the name of Allah. Computer Engineering Department Sharif University of Technology CE443- Computer Networks

Announcements. CS 5565 Network Architecture and Protocols. Queuing. Demultiplexing. Demultiplexing Issues (1) Demultiplexing Issues (2)

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

Christian Tschudin (basierend auf einem Foliensatz von C. Jelger und T. Meyer) Departement Mathematik und Informatik, Universität Basel

Lecture 2. Outline. Layering and Protocols. Network Architecture. Layering and Protocols. Layering and Protocols. Chapter 1 - Foundation

COMP/ELEC 429/556 Introduction to Computer Networks

How to write a Measurement Telnet Server

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

Network Socket Programming - 3 BUPT/QMUL

Network programming(i) Lenuta Alboaie

Communication. Communication. Distributed Systems. Networks and protocols Sockets Remote Invocation Messages Streams. Fall /10/2001 DoCS

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

The Berkeley Sockets API. Networked Systems Architecture 3 Lecture 4

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

Group-A Assignment No. 6

CSCI 415 Computer Networks Homework 2 Due 02/13/08

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

JFx Joystick. June 21, Unrestricted Distribution. Revision 1.00

CS307 Operating Systems Processes

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

Types (Protocols) Associated functions Styles We will look at using sockets in C Java sockets are conceptually quite similar

CSC209H Lecture 9. Dan Zingaro. March 11, 2015

UNIX Sockets. Developed for the Azera Group By: Joseph D. Fournier B.Sc.E.E., M.Sc.E.E.

Introduction to Client-Server Model

UNIX Sockets. COS 461 Precept 1

Network Communication

SOCKET PROGRAMMING. What is a socket? Using sockets Types (Protocols) Associated functions Styles

Networked Applications: Sockets. Goals of Todayʼs Lecture. End System: Computer on the ʻNet. Client-server paradigm End systems Clients and servers

TCP Network Programming in C

System Programming. Sockets: examples

ICT 6544 Distributed Systems Lecture 5

Sockets 15H2. Inshik Song

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

Assignment description: This is a C++ project. The comms class containing the

Assignment 1: tcpbridge

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

Project 3. Reliable Data Transfer over UDP. NTU CSIE Computer Networks 2011 Spring

// socket for establishing connections

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

Network Programming Week #1. K.C. Kim

CSE 333 Lecture 16 - network programming intro

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

The User Datagram Protocol

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

NETWORK AND SYSTEM PROGRAMMING

CSMC 412. Computer Networks Prof. Ashok K Agrawala Ashok Agrawala Set 2. September 15 CMSC417 Set 2 1

Transcription:

Simple network applications using sockets (BSD and WinSock) Revision 1 Copyright 2002 - Clifford Slocombe sockets@slocombe.clara.net COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 1 OF 8

Table of Contents Introduction...3 Socket APIs...3 Byte order and structure packing...4 Establishing a communication session...4 Client...4 Server...4 A simple example application...5 Client code for BSD/WinSock...5 Server code for BSD/WinSock...7 Practical applications...8 COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 2 OF 8

Introduction While general-purpose network applications, such as telnet and FTP are useful, it is often necessary to implement customised communicating applications. The ability to leverage the security, flexibility, and universality of TCP/IP is extremely valuable. The ability of TCP/IP to support multiple simultaneous communicating applications makes it well suited to multi-threaded applications, and supports the efficient use of available physical communication links. This document describes only the use of TCP sockets, which provide character stream communication. UDP sockets, which provide data packet, or datagram communication, are not discussed, although much of the information contained herein is applicable to both UDP and TCP. The socket API does not specify any particular communications protocol, however it is most commonly used with TCP/IP. TCP/IP is assumed throughout this document. A WinSock TCP/IP application may communicate with a BSD socket TCP/IP application, allowing cross-platform networking. This document is an introduction to building communicating applications using both BSD and Windows socket APIs. It presents a simple client/server application coded to both APIs that demonstrates the principles. Windows sockets (WinSock) is specific to Windows and is similar but not identical to BSD. The BSD socket API has been implemented on many platforms including Linux, and is available for embedded systems and real-time operating systems. Socket APIs BSD compatible socket API are available for many platforms; existing TCP/IP application code for UNIX or Linux platforms may be ported with little of no modification. Windows implements the Windows Sockets API. Windows Sockets is based on, but not entirely compatible with BSD 4.3 sockets. Apart from proprietary initialisation and clean-up functions, needed to support the windows environment, there are a number of important differences between BSD sockets and Windows Sockets, the main ones are as follows: Socket descriptors (or handles) in Windows are of type SOCKET, in BSD they are of type int. This is important for a number of reasons, SOCKET is unsigned, and in BSD the value -1 is used to indicate an error. In Windows, the manifest constant INVALID_SOCKET is used to indicate an error. In BSD, socket descriptors and file descriptors are entirely compatible, allowing the file I/O functions such as read(), and write(), to be used with socket streams. In Windows this is not guaranteed to be the case, so the socket specific equivalents such as recv(), and send(), should be used. In the example code I have used socket specific functions for both the BSD and WinSock applications. This keeps things simpler and makes the porting of code between the two platforms simpler. Because the Windows Sockets API is not compatible with the file I/O API, two functions common to both I/O and sockets in BSD have been renamed in Windows. These are close(), and ioctl(), called closesocket(), and ioctlsocket (), respectively in Windows. Code that does not strictly use the FD_XXX macros for accessing fd_set structures will not work correctly with the select() function. Windows Sockets error codes are not available via the errno variable. The function WSAGetLastError() returns socket error codes. BSD error code manifest constants are defined for compatibility, but Microsoft recommend that the WSA prefixed error codes are used instead. Windows Sockets functions return SOCKET_ERROR on error, BSD sockets code commonly check for the value 1 to test for errors. Note that under Windows, using C++, Microsoft Foundation Classes (MFC) provides a wrapper class (Csocket). I shall leave the reader to investigate this, and concentrate on teh C API since this is more universal. COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 3 OF 8

Byte order and structure packing Care must be taken when transferring data between two machines over byte ordering and structure packing, which may differ between different CPU and/or compilers. This means, for example that a multi-byte integer, or a data structure transmitted as a byte stream from one computer, may not be directly read into the same data type on another. To help overcome some of these problems a convention known as network byte order is used. A number of macros are used to convert between the local host byte order and network byte order. The macros impose no overhead on architectures wherethe host byte order matches network byte order. The macros defined in <in.h> are as follows: Macro htonl htons ntohl ntohs Description Convert a long from host to network byte ordering. Convert a short from host to network byte ordering. Convert a long from network to host byte ordering. Convert a short from network to host byte ordering. Differences in byte ordering between the CPU and the network convention may or may not be important for application data. It is however important with respect to network addressing, where the use of the macros is essential to ensure correct addressing and portability of code. Establishing a communication session A connection is initiated an application running on one node on the network, and accepted by another application running on another node (or possibly the same node). Often a client-server relationship is established, where the client requests a connection to the server, and the server can accept one or more simultaneous connections. It is also possible to create peer-peer applications where bothe ends of a connection may either initiate or accept connections. The example considered here is of the client-server form. It is also very simple in that the server may only accept a connection from and service one client at a time. To service multiple clients (a concurrent server), the server application would have to accept a connection and then spawn a separate thread to service the client, before returning to 'listen' for other clients. Since creating multiple threads or tasks is operating system dependent, I have not dealt with it in detail here. Client The steps taken by a client application during a communication session are: Obtain a socket descriptor (handle) by calling the socket() function. Initialise a sockaddr_in structure with addressing data. Connect to the server by calling the connect() function. Send and receive data as necessary by calling the send() and recv() functions as necessary. Alternatively, under BSD socket API the file IO functions read() and write() may be used. Terminate connection by calling close() (BSD) or closesocket() (WinSock). Server The steps taken by a client application during a communication session are: Obtain a server socket descriptor (handle) by calling the socket() function. Initialise a sockaddr_in structure with addressing data. Bind the addressing information to the socket by calling the bind() function. Wait for connection requests on the selected port by calling listen(). COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 4 OF 8

Accept the connection (and get the client socket descriptor) by calling accept(). If the application is a concurrent server, a new thread world be spawned (or an existing thread awoken) to accept the connection before looping back to listen. The new thread would communicate with the client using socket descriptor returned by accept(). Send and receive data as necessary by calling the send() and recv() functions as necessary. Alternatively, under BSD socket API the file IO functions read() and write() may be used. Terminate the client connection by calling close() (BSD) or closesocket() (WinSock) for the client descriptor. When the server terminates, close the server socket by calling close() (BSD) or closesocket() (WinSock) for the client descriptor. A simple example application The application described herein implements a simple TCP/IP application called rprint. It is intended to demonstrate the basics of communicating data via TCP/IP with the minimum of superfluous code. The simplicity is intended to enable the reader to appreciate the essential requirements of TCP/IP applications, without unnecessarily elaborate application code. The rprint application is a client/server application in two parts, a client application, and a server application. For simplicity (and portability), the applications are console (text) mode applications, allowing us to ignorethe added complexity and rigors of GUI applications. The client program is called rprint, it takes an IP address and a port number, and then any number of arbitrary strings as parameters, for example: rprint 10.0.0.1 6000 Hello, world The strings are sent with spaces delimiting them and a NUL terminator to the port at the IP address. The server end is called rprintsvr, and simply prints any NUL terminated string it receives followed by a newline character. The application is very simple, data flows in one direction only, and the server can service exactly one client at a time. The code has been verbosely commented since it is intended to be instructive. It also contains conditional compilation so that it should build on either WinSock or BSD environments. If you intend to develop on only one environment, you could render the code more readable by removing the parts related to the alternate environment. However, writing the code for both platforms in a single source does serve to highlight the differences. Client code for BSD/WinSock / rprint console mode socket client Clifford Slocombe - December 2002 A simple demonstration of a socket client application Sends null terminated string of words passed on the command line to remote server for display. USAGE: rprint <ipaddr> <port> <word> [<word>...] e.g. rprint 10.0.0.1 6000 This is an rprint message. / #include <winsock.h> / Windows Sockets header / #include <socket.h> / BSD sockets library / #include <io.h> / BSD sockets use file I/O / #include <in.h> / network byte order macros / / These error macros are used in Winsock, and are defined here so that the BSD code can be the same. Avoiding lots (more) of messy conditional compilation / #if!defined SOCKET_ERROR #define SOCKET_ERROR -1 #if!defined INVALID_SOCKET #define INVALID_SOCKET -1 #include <string.h> COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 5 OF 8

int main( int argc, charargv ) / Console mode, so main() is OK / WSADATA winsock_info ; / Required by WASStartup, gets filled with information about WinSock implementation / SOCKET sd ; / Socket descriptor (not a file handle in Windows) / SOCKADDR_IN name ; / IP addressing data the term name is a BSD convention / int sd ; / Socket descriptor (file handle in BSD) / struct sockaddr_in name ; / IP addressing data the term name is a BSD convention / int status ; int param ; / WSAStartup is mandatory in WinSock applications / status = WSAStartup( MAKEWORD(1,1), &winsock_info ) ; / No Startup required in BSD, set status to zero so subsequent test suceeds / status = 0 ; if( status == 0 ) / Get a socket descriptor / sd = socket( PF_INET, SOCK_STREAM, 0 ) ; / Test for valid socket... / if( sd!= INVALID_SOCKET ) / Got a good socket, so fill in addressing data / name.sin_family = AF_INET ; / Internet addressing / name.sin_addr.s_addr = inet_addr( argv[1] ) ; / IP address (convert from a.b.c.d string) / name.sin_port = htons( (u_short)atoi(argv[2]) ) ; / Port, (network byte order) / / If IP a.b.c.d address string was valid / if(name.sin_addr.s_addr!= INADDR_NONE ) / Connect to server, (cast address to generic socket address) / status = connect( sd, (struct sockaddr)&name, sizeof(name) ) ; else / Ensure loop will not start if error / status = SOCKET_ERROR ; / For each remaining parameter, or until error... / for( param = 3; status!= SOCKET_ERROR && param < argc; param++ ) / Send parameter string / status = send( sd, argv[param], strlen(argv[param]), 0 ) ; / If no error... / if( status!= SOCKET_ERROR ) / Send a space character / status = send( sd, " ", 1, 0 ) ; / Terminate transmission with a NUL character / (void)send( sd, "\0", 1, 0 ) ; / Close socket with WinSock specific function, BSD close() not guaranteed because descriptor is not a file handle / closesocket( sd ) ; close( sd ) ; / WSACleanup is mandatory in WinSock applications / WSACleanup() ; return( 0 ) ; COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 6 OF 8

Server code for BSD/WinSock / rprintsvr console mode socket server Clifford Slocombe - December 2002 A simple demonstration of a BSD Sockets server application Recieves NUL terminated strings abd displays them. USAGE: rprintsvr port Port parameter must match that used by client / #include <string.h> #include <stdlib.h> #include <stdio.h> #include <winsock.h> / Windows Sockets header / #include <socket.h> / BSD sockets library / #include <io.h> / BSD sockets use file I/O / #include <in.h> / network byte order macros / / These error macros are used in Winsock, and are defined here so that the BSD code can be the same. Avoiding lots (more) of messy conditional compilation / #if!defined SOCKET_ERROR #define SOCKET_ERROR -1 #if!defined INVALID_SOCKET #define INVALID_SOCKET -1 int main( int argc, charargv ) / Console mode, so main() is OK / unsigned int port ; SOCKET server_sd ; / Server socket descriptor / SOCKET client_sd ; / Client socket descriptor / SOCKADDR_IN server_name ; / Server IP addressing / SOCKADDR_IN client_name ; / Client IP addressing / int server_sd ; / Server socket descriptor / int client_sd ; / Client socket descriptor / struct sockaddr_in server_name ; / Server IP addressing / struct sockaddr_in client_name ; / Client IP addressing / int status = SOCKET_ERROR ; int addr_len = sizeof(client_name) ; char c ; / Get port address from command line / port = atoi( argv[1] ) ; / get a server side socket / server_sd = socket( PF_INET, SOCK_STREAM, 0 ) ; / accept() requires pointer to address length so address length must be assigned to a variable / / In BSD valid sockets are positive integers / if( server_sd!= INVALID_SOCKET ) / Got a good socket, so fill in addressing data / memset( &server_name, sizeof(server_name), 0 ) ; server_name.sin_family = AF_INET ; / Internet addressing / server_name.sin_addr.s_addr = INADDR_ANY ; / accept input from any client / server_name.sin_port = htons( port ) ; / but just at this port / / Bind addressing to server socket / status = bind( server_sd, (struct sockaddr)&server_name, sizeof(struct sockaddr) ) ; if( status!= ERROR ) / Wait for activity on bound port, in this case only allowing one pending connection, because this is not a concurrent server / status = listen( server_sd, 1 ) ; while( status!= ERROR ) / accept the connection, binding it to the client descriptor / client_sd = accept( server_sd, (struct sockaddr)&client_name, &addr_len ) ; if( client_sd >= 0 ) / Recieve characters, and display them until a NUL is read / COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 7 OF 8

status = recv( client_sd, &c, 1, 0 ) ; while( c!= '\0' && status!= SOCKET_ERROR ) putchar( (int)c ) ; / display / status = recv( client_sd, &c, 1, 0 ) ; / get next / putchar( '\n' ) ; / Close client socket when done / / Close socket with WinSock specific function, BSD close() not guaranteed because descriptor is not a file handle / closesocket( client_sd ) ; close( client_sd ) ; else status = ERROR ; / Close server socket if it was ever opened / if( server_sd!= SOCKET_ERROR ) / Close socket with WinSock specific function, BSD close() not guaranteed because descriptor is not a file handle / closesocket( server_sd ) ; close( server_sd ) ; return( 0 ) ; Practical applications The example in the section illustrates the essentials of network communication using sockets. In a practical application, it would be likely that multiple clients could be serviced simultaneously, and that data would be exchanged in both directions. Typical server applications incorporate a loop, where the accept is performed. For each accepted connection, a task is either spawned or awoken, the client socket descriptor is passed to the task, so that that client can be serviced, while the server loop is ready to accept new connections. COPYRIGHT 2002 - CLIFFORD SLOCOMBE PAGE 8 OF 8