350 likes | 359 Views
Learn about the client/server paradigm, socket programming with TCP and UDP, and the functions and structures used in C sockets.
E N D
Data Communication and Networks Lecture 10 Sockets in C and JAVA November 21, 2002 Joseph Conron Computer Science Department New York University conron@cs.nyu.edu
Client/Server Paradigm • Basis for most application layer communications • Client (typically) • Initiates communication • Sends requests and receives responses • Interacts with just a few servers at a time • Server (typically) • Waits for incoming requests • Receives requests and sends responses • Interacts with many clients concurrently
The Socket Abstraction • Socket represents a service point used by an application to interact with a transport service. • In C, a socket is similar to a file descriptor and is used in read(), write(), and ioctl() calls • In Java, Socket is a class. • Java sockets provide (almost) all of the BSD socket semantics.
Socket Programming Socket API • introduced in BSD4.1 UNIX, 1981 • explicitly created, used, released by apps • client/server paradigm • two types of transport service via socket API: • unreliable datagram (UDP) • reliable, byte stream-oriented (TCP)
Client must contact server server process must first be running server must have created socket that accepts client’s connection request Client contacts server by: creating client-local TCP socket specifying IP address, port number of server process When client creates socket: client TCP establishes connection to server TCP When contacted by client, server TCP creates new socket for server process to communicate with client allows server to talk with multiple clients Socket Programming with TCP
process process TCP with buffers, variables TCP with buffers, variables socket socket Socket-programming using TCP Socket:a door between application process and end-end-transport protocol (UCP or TCP) TCP service:reliable transfer of bytes from one process to another controlled by application developer controlled by application developer controlled by operating system controlled by operating system internet host or server host or server
UDP: no “connection” between client and server no handshaking sender explicitly attaches IP address and port of destination server must extract IP address, port of sender from received datagram UDP: transmitted data may be received out of order, or lost UDP provides unreliable transfer of groups of bytes (“datagrams”) between client and server application viewpoint Socket programming with UDP
Sockets in C • Host addresses separate from sockets: • Different functions for TCP or UDP • Not discussed: socket options via ioctl() (read about these in your own) • Compare this to the Java Socket class!
Sockets in C: Summary of Function Calls socket() Connection Oriented Protocol bind() socket() listen() connect() accept() Connection write() read() read() write() Server Client
Sockets in C: Summary of Function Calls (cont.) socket() bind() socket() Connectionless Protocol bind() recvfrom() sendto() sendto() recvfrom() Server Client
Sockets in C:The structures sockaddr and sockaddr_in • Contain address information associated with a socket • They have the same length in bytes • sockaddr_in applies to Internet protocols (contains IP address and port) • Avoid use of sockaddr (sometimes needed for cast) struct sockaddr { u_short sa_family; u_short sa_data[14]; } struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; // unused }
Sockets in C: Filling the sockaddr_in structure Example I: sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); sock_addr.sin_port = htons(0); sock_addr.sin_family = AF_INET; Example II: sock_addr.sin_addr.s_addr = inet_addr(“128.59.69.7”); sock_addr.sin_port = htons(5115); sock_addr.sin_family = AF_INET
Sockets in C: Filling the sockaddr_in structure • INADDR_ANY is used for accepting connections on any • local interface if the system is multi-homed • We assign a zero port number when filling the sockaddr_in • data structure, if we want a free port to be allocated to a • socket during the bind() procedure • htonl(), htons() handle byte-ordering differences between computer • architectures and network protocols • >> redundant in Sun’s sparc • >> needed in x86 architectures
Sockets in C: The socket() function int socket(int family, int type, int protocol) Example: if (( sock = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf(": error opening socket"); exit(-1); } - Creates a socket: Not associated with a client or server process yet - SOCK_STREAM (TCP) vs. SOCK_DGRAM (UDP)
Sockets in C: The bind() function • int bind(int sockfd, struct sockaddr *myaddr, int addrlen) • Example: • if (bind(sock, • (struct sockaddr *) &sock_addr, • sizeof(sock_addr)) < 0) • { • printf(": error binding socket to local address"); • exit(-1); • } • -Binds a socket to an IP address and port. • - Used by servers to specify the well-known port t they will listen for • connections
Sockets in C: The connect() function int connect (int sockfd, struct sockaddr *myaddr, int addrlen) Example: if (connect(sock, ( struct sockaddr *) &sock_addr, sizeof sock_addr) == -1) { printf(": socket connection error"); exit(-1); } - used in connection oriented communications (TCP) - used by clients to connects to a server
Sockets in C: The read() and write() functions int read(int sockfd, char *buf, unsign int nbytes) int write(int sockfd, char *buf, unsign int nbytes) Examples: if (write(sock, message, size) <0 ) { printf(": error writing to remote host"); exit(-1); } bytes_received = read(sock, reply, sizeof(reply)); - used in connection oriented communications (TCP) - used for requesting and transmitting data
Sockets in C: The sendto() and recvfrom() functions int recvfrom(int sockfd, char *buf, int nbytes, int flags, struct sockaddr *from, int addrlen) int sendto(int sockfd, char *buf, int nbytes, int flags, struct sockaddr *to, int addrlen) - used in connectionless communications (UDP) - peer end-system address information is passed or returned from these function calls (why?)
Sockets in C:Resolving Host Names and Port numbers (see Comer chap 5 - 7) Struct sock_addr_in sin; IP Address - gethostbyname((char *) host) struct hostent *phe; if (phe = gethostbyname(host)); memcpy(&sin.sin_addr, phe->h_addr, phe->h_length); else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) /* Error - can’t get host ip address */ Port - getservbyname((char *) name, (char *) proto) struct servent *pse; if (pse = getservbyname (name, “tcp”)); sin.sin_port = pse->port; else if((sin.sin_port = htons((u_short)atoi((name))) == 0) /* Error - can’t get service port */
Sockets and processes • Like file descriptors, sockets are inherited by child processes • Socket disappears when all processes have closed it • Servers use socket inheritance to pass incoming connections to slave server processes
Select • Wait for first fd in a set to become ready, or a timeout. • Use for asynchronous I/O or multiple concurrent operations within one thread. #include <sys/types.h> #include <sys/time.h> int select (width, readfds, writefds, exceptfds, timeout); int width; fd_set *readfds, *writefds, *exceptfds; struct timeval *timeout;
Select Example int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); exit(0); }
What do I need to include? - In Unix: #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> - In Windows NT/95 #include <windows.h> #include <sys/types.h> #include <winsock.h>
Sockets in JAVA • InetAddress • Represents an IP Address • ServerSocket • Passive socket (server) • Socket • Active socket (client) • DatagramSocket • UDP socket • DatagramPacket • Represents a UDP datagram
create socket, connect to hostid, port=x create socket, port=x, for incoming request: clientSocket = Socket() welcomeSocket = ServerSocket() TCP connection setup wait for incoming connection request connectionSocket = welcomeSocket.accept() send request using clientSocket read request from connectionSocket write reply to connectionSocket read reply from clientSocket close connectionSocket close clientSocket Client/server socket interaction: TCP Server (running on hostid) Client
Example: Java client (TCP) import java.io.*; import java.net.*; class TCPClient { public static void main(String argv[]) throws Exception { String sentence; String modifiedSentence; BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); Socket clientSocket = new Socket("hostname", 6789); DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); Create input stream Create client socket, connect to server Create output stream attached to socket
Example: Java client (TCP), cont. Create input stream attached to socket BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); sentence = inFromUser.readLine(); outToServer.writeBytes(sentence + '\n'); modifiedSentence = inFromServer.readLine(); System.out.println("FROM SERVER: " + modifiedSentence); clientSocket.close(); } } Send line to server Read line from server
Example: Java server (TCP) import java.io.*; import java.net.*; class TCPServer { public static void main(String argv[]) throws Exception { String clientSentence; String capitalizedSentence; ServerSocket welcomeSocket = new ServerSocket(6789); while(true) { Socket connectionSocket = welcomeSocket.accept(); BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); Create welcoming socket at port 6789 Wait, on welcoming socket for contact by client Create input stream, attached to socket
Example: Java server (TCP), cont DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); clientSentence = inFromClient.readLine(); capitalizedSentence = clientSentence.toUpperCase() + '\n'; outToClient.writeBytes(capitalizedSentence); } } } Create output stream, attached to socket Read in line from socket Write out line to socket End of while loop, loop back and wait for another client connection
Client create socket, port=x, for incoming request: serverSocket = DatagramSocket() create socket, clientSocket = DatagramSocket() Create, address (hostid, port=x, send datagram request using clientSocket read request from serverSocket write reply to serverSocket specifying client host address, port umber read reply from clientSocket close clientSocket Client/Server socket interaction: UDP Server (running on hostid)
Example: Java client (UDP) import java.io.*; import java.net.*; class UDPClient { public static void main(String args[]) throws Exception { BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); DatagramSocket clientSocket = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName("hostname"); byte[] sendData = new byte[1024]; byte[] receiveData = new byte[1024]; String sentence = inFromUser.readLine(); sendData = sentence.getBytes(); Create input stream Create client socket Translate hostname to IP address using DNS
Example: Java client (UDP), cont. Create datagram with data-to-send, length, IP addr, port DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876); clientSocket.send(sendPacket); DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); clientSocket.receive(receivePacket); String modifiedSentence = new String(receivePacket.getData()); System.out.println("FROM SERVER:" + modifiedSentence); clientSocket.close(); } } Send datagram to server Read datagram from server
Example: Java server (UDP) import java.io.*; import java.net.*; class UDPServer { public static void main(String args[]) throws Exception { DatagramSocket serverSocket = new DatagramSocket(9876); byte[] receiveData = new byte[1024]; byte[] sendData = new byte[1024]; while(true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); Create datagram socket at port 9876 Create space for received datagram Receive datagram
Example: Java server (UDP), cont String sentence = new String(receivePacket.getData()); InetAddress IPAddress = receivePacket.getAddress(); int port = receivePacket.getPort(); String capitalizedSentence = sentence.toUpperCase(); sendData = capitalizedSentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); serverSocket.send(sendPacket); } } } Get IP addr port #, of sender Create datagram to send to client Write out datagram to socket End of while loop, loop back and wait for another datagram
Socket Programming Summary • BSD sockets are the standard • The basic interface (C) is arcane • Socket class in Java makes life easier without sacrificing functionality • But one could hide the complexity of C with well thought out functions (see Comer, D.E. and Stevens, D.L. Internetworking with TCP/IP: Volume III: Client-Server Programming and Applications, BSD socket version chapter 7)