Download presentation
Presentation is loading. Please wait.
Published byChester Hall Modified over 8 years ago
1
Client-Server Model ● Frequently used programming paradigms – client-server model: one process provides services for a set of client process, eg. HTTP server-web browser. X server- X client. – master-slave: one master process assigns tasks to a group of slave processes, eg. Cluster Scheduler-Cluster Node, kernel- user processes.
2
Using Shell Programs ● popen: NAME popen, pclose - process I/O SYNOPSIS #include FILE *popen(const char *command, const char *type); int pclose(FILE *stream); DESCRIPTION The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read-only or write-only. The command argument is a pointer to a null-terminated string contain- ing a shell command line. This command is passed to /bin/sh using the -c flag; interpretation, if any, is performed by the shell. The type argument is a pointer to a null-terminated string which must be either 'r' for reading or 'w' for writing.
3
Using Shell Programs ● popen: The return value from popen() is a normal standard I/O stream in all respects save that it must be closed with pclose() rather than fclose(). Writing to such a stream writes to the standard input of the command; the command's standard output is the same as that of the pro- cess that called popen(), unless this is altered by the command itself. Conversely, reading from a ''popened'' stream reads the command's stan- dard output, and the command's standard input is the same as that of the process that called popen. Note that output popen streams are fully buffered by default. The pclose function waits for the associated process to terminate and returns the exit status of the command as returned by wait4.
4
Using Shell Programs ● popen: ● System fp = popen( "who|sort", "r" ); /* open the command */ while ( fgets( buf, 100, fp ) != NULL )/* read from command */ printf("%3d %s", i++, buf ); /* print data */ pclose( fp ); /* IMPORTANT! */ return 0; system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.
5
Converting a file descriptor to a stream ● Streams: – Buffered for efficiency – Easier data conversion (fprintf ) ● FILE *file: file=fdopen(fd)
6
POPEN.C pipe(p) fork() | +--------------+----------+ close(p[1]); close(p[1]); fp=fdopen(p[0],”r”); dup2(p[1],1); return fp; execl(“/bin/sh”,”sh”,”-c”, cmd, NULL);
7
Sockets
9
● Setting up a server 1. get a socket = phone line 2. bind address to socket = get a phone number 3. listen = allow incoming calls 4. connect,write,close=provide service.
10
Sockets ● Setting up a server 1. get a socket = phone line 2. bind address to socket = get a phone number 3. listen = allow incoming calls 4. connect,write,close=provide service. #include int socket(int domain, int type, int protocol); domain tells the call where the socket is to be used. For example PF_INET specifies the internet domain for networking. Another domain, is PF_UNIX, which is used if the processes are on the same machine. The type of the socket to be created specifies whether it is to be used in a connection or connectionless mode. SOCK_STREAM specifies a connection oriented link, SOCK_DGRAM a connectionless link. The final parameter, protocol, specifies which protocol should be used by this socket. This will normally be set to 0, in which case, by default, a SOCK_STREAM socket wiIl use TCP and a SOCK_DGRAM socket will use UDP-both standard UNIX protocols. The socket system call normally returns a non-negative integer which is the socket file descriptor, which enables sockets to be treated using the familiar UNIX file model.
11
Sockets ● Setting up a server 1. get a socket = phone line 2. bind address to socket = get a phone number 3. listen = allow incoming calls 4. accept,write,close=provide service. #include int bind(int sockfd, const struct sockaddr *address,size_t add_len); The first parameter, sockfd, is the socket file descriptor originally returned by the socket system call. The second parameter is a pointer to a generic socket structure. However, because we are sending information across the network in our example, we will actually provide the address of the relevant struct sockaddr_in which contains the addressing information for our server. The final parameter holds the size of the actual socket structure used. If the bind call is successful then it returns 0. On error, the bind call returns -1, which may happen if a socket already exists for the address. The errno will then contain EADDRINUSE.
12
Sockets ● Setting up a server 1. get a socket = phone line 2. bind address to socket = get a phone number 3. listen = allow incoming calls 4. accept,write,close=provide service. #include int listen(int sockfd, int queue-size)int listen(int sockfd, int queue-size); The sockfd parameter is as above. The server can queue up to queue-size incoming connection requests.
13
Sockets ● Setting up a server 1. get a socket = phone line 2. bind address to socket = get a phone number 3. listen = allow incoming calls 4. accept,write,close=provide service. include #include int accept(int sockfd, struct sockaddr *address,size-t *add_len); The accept system call is passed the listening socket descriptor returned from the original socket system call. On completion, the return value is the new socket id to be used for the communication. The address parameter is filled out with the information about the client. However, because this is a connection oriented communication the server very rarely needs to know the address of the client, and therefore address can be replaced with NULL. If address is not NULL then the variable pointed to by add_len should initially contain the length of the address structure described by address. On the return of the accept call, *add_len will hold the number of bytes actually copied.
14
Sockets 4. accept,write,close=provide service. #include read write Also: size_t recv(int sockfd, void *buffer, size_t length,int flags); size_t send(int sockfd, const void *buffer, size_t length,int flags); The recv call specifies the file descriptor to read the data from, the buffer into which the data should be put, and the length of the buffer. As with read, recv returns the amount of data read. The flags parameter affects the way in which the data can be received. The possible values are: MSG_PEEK: The process can look at the data without actually receivingit. MSG_OOB: Normal data is bypassed and the process only receives out of band data, for example, an interrupt signal. MSG_WAITALL: The recv call will only return when the full amount of data is available. send behaves just like write if the flags parameter is set to 0. It sends the message contained in buffer to sockfd, the local socket. The length parameter specifies the length of buffer. As with recv the flags parameter affects the way that messages are sent. The possible values are: MSG-OOB: Send 'out of band' data.
15
Client ● Setting up a client 1. get a socket = phone line 2. connect 3. write,close=provide service.
16
Sockets:Debugging, Info ● Using web browser: – enter ip address: sauron.cs.kent.edu:7001 – tcpserver.c listening on 7001 ● Look at man 7 socket ● Look at socklib.c on class page ● Look at rfc1945.txt on class page
17
TimeServer2 main() { int sock, fd; sock = make_server_socket( PORTNUM ); if ( sock == -1 ) oops( "make_server_socket" ); while( ( fd = accept(sock,NULL,NULL) ) != -1 ) { process_request(fd); close(fd); } process_request(fd) /* * send the date out to the client via fd */ { int pid = fork(); if ( pid == -1 ) return ; /* error getting a new process */ if ( pid != 0 ) return; /* parent does not wati */ /* child code here */ dup2( fd, 1 ); /* moves socket to fd 1 */ close(fd); /* closes socket */ execlp("date","date",NULL); /* exec date */ oops("execlp date"); }
18
TimeServer2d main() { int sock, fd; sock = make_server_socket( PORTNUM ); if ( sock == -1 ) oops( "make_server_socket" ); while( ( fd = accept(sock,NULL,NULL) ) != -1 ) { process_request(fd); close(fd); } process_request(fd) /* * send the date out to the client via fd */ { int pid = fork(); if ( pid == -1 ) return ; /* error getting a new process */ if ( pid != 0 ){ /* parent */ wait(NULL); /* do we have to wait? */ return; /* what about zombies? */ } /* child code here */ dup2( fd, 1 ); /* moves socket to fd 1 */ close(fd); /* closes socket */ execlp("date","date",NULL); /* exec date */ oops("execlp date");}
19
Windows Sockets ● Initialize the WinSock DLL ● int WSAStartup( WORD wVersionRequired, LPWSADATA lpWSAData);
20
Windows Sockets wVersionRequired – Indicates the highest version of the WinSock DLL you need – Returns a non-zero value if the DLL cannot support the version you want – Low byte specifies the major version – High byte specifies the minor version – 0x0101 version 1.1 lpWSAData points to a WSADATA structure that returns information on the configuration of the DLL WSAGetLastError() for error number
21
Allocate a Socket Sockets are analogous to handles – A communication channel Call socket() to create (or open) a socket – Actually a HANDLE
22
Allocate a Socket – Server: “Listening socket” for client connection requests typedef unsigned int SOCKET; SOCKET socket(int af, int type, int protocol);
23
Allocate a Socket – Server: “Listening socket” for client connection requests typedef unsigned int SOCKET; SOCKET socket(int af, int type, int protocol);
24
Allocate a Socket – af denotes the address family – PF_INET or AF_INET designates the Internet protocol – type specifies connection-oriented ( SOCK_STREAM ) or datagram communications ( SOCK_DGRAM ) – protocol unnecessary for TCP/IP ● Use 0 socket returns INVALID_SOCKET upon failure
25
BIND Next, bind the socket to its address and service endpoint int bind ( SOCKET s, const struct sockaddr *saddr, int namelen); – s is an “unbound” SOCKET returned by socket() – saddr specifies the address family and protocol-specific information – namelen is sizeof(sockaddr) Returns SOCKET_ERROR in case of error
26
BIND sa_data is protocol-specific TCP/IP sockaddr_in : struct sockaddr_in { shortsin_family; // AF_INET u_shortsin_port; structin_addr sin_addr; //4-byte IP addr char sinzero [8]; }; typedef struct sockaddr_in SOCKADDR_IN, *PSOCKADDR_IN;
27
BIND List of hosts (mapped to IP addresses) can be found in %SystemRoot%\system32\drivers\etc\hosts List of Services(mapped to services) can be found in %SystemRoot%\system32\drivers\etc\services If you bind to a specific IP address, you can only receive incoming packets over that IP address If you have more than one IP address, bind to hotnl(INADDR_ANY) “host to network long”
28
BIND BOOL WINAPI WNetGetHostAddress( LPCSTR lpszHost, LPCSTR lpszService, LPCSTR lpszProto, LPSOCKADDR lpAddr) /* Fill in a SOCKADDR using host, protocol, service */ { LPHOSTENT lpHost; LPSERVENT lpServ; SOCKADDR_IN sin; ZeroMemory(&sin, sizeof(sin));
29
BIND sin.sin_family = PF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); if(lpszHost != NULL) { lpHost = gethostbyname(lpszHost); if(lpHost != NULL) { CopyMemory(&sin.sin_addr, lpHost->h_addr_list[0], lpHost->h_length); } lpServ = getservbyname(lpszService, lpszProto);
30
BIND if(lpServ != NULL) { sin.sin_port = lpServ->s_port; ZeroMemory(sin.sin_zero, sizeof(sin.sin_zero)); CopyMemory(lpAddr, &sin, sizeof(SOCKADDR)); return TRUE; /* lpAddr is now ready for bind() */ } return FALSE; } The address returned by WNetGetHostAddress() can be passed directly to the bind() function
31
LISTEN listen() makes server available for client connection – Socket goes from “bound” to “listening” state int listen(SOCKET s, int nQueueSize); nQueueSize indicates the number of connection requests you are willing to have queued at the socket – Up to SOMAXCON (5 for 1.1, “unlimited” in 2.0)
32
Accept – The call to listen() places the socket into the listening state – The server application calls accept() ● Returning a “connected socket” – accept() blocks until a client request for a connection arrives – accept() return value gives the server a new socket for exchanging data
33
Accept SOCKET accept( SOCKET s, /* Listening socket */ LPSOCKADDR lpAddr, /* Find client details here */ LPINT lpnAddrLen /* Length of the returned structure */);
34
Client int connect( SOCKET s, LPSOCKADDR lpName, int nNameLen); lpName points to a SOCKADDR structure designating the server machine name and port address
35
Data Exchange – Partner stations exchange data using send() and recv() – send() and recv() have identical arguments: int send ( int recv ( SOCKET s, LPSTR lpBuffer, int nBufferLen,int nBufferLen, int nFlags); int nFlags);
36
Data Exchange – nFlags == MSG_OOB indicates urgency ● OOB for out-of-band – MSG_PEEK can be used to peek at the data without removing it – These are standard Berkeley Sockets calls ● But read() and write() are more common under UNIX – Not atomic or message oriented ● Loop until full message is received ● Or sent, although incomplete send() is rare
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.