Upload
tanisha-patrick
View
28
Download
0
Embed Size (px)
DESCRIPTION
UNIX Domain sockets. The Linux Programming Interface (ch 57) UNIX Network Programming – Vol 1, 3ed (ch 15). Using Sockets in UNIX domain. Unnamed sockets – socketpair( ) Does not bind to transport layer ports Creates a pair of sockets that are connected - PowerPoint PPT Presentation
Citation preview
UNIX Domain sockets
The Linux Programming Interface
(ch 57)
UNIX Network Programming – Vol 1, 3ed (ch 15)
Using Sockets in UNIX domain
• Unnamed sockets – socketpair( )– Does not bind to transport layer ports
– Creates a pair of sockets that are connected
– Typically used to communicate between related processes
– Communications similar to pipe
• Traditional sockets in UNIX– Binds to transport layer ports
– Allows independent processes to communicate
– Creates a file type object (socket)• Any process that can access the socket can use it.
– Does not use network (IP) layer
2
socketpair( )
• int socketpair (int family, int type, int protocol, int sockfd[2]);– Family must be AF_LOCAL
– Type may be SOCK_STREAM or SOCK_DGRAM
– protocol must be 0
– On success, the pair of socket descriptors (sockfd) are connected together and available for communications
• #include <sys/sockets>
• Return zero on success, -1 on fail
• In Linux, sockets are full duplex (can both read and write), however, POSIX standard does not require full duplex.
3
sockpair.cpp
4
#define LB_SIZE 128int main ( ){
time_t now;char child_buf[LB_SIZE], parent_buf[LB_SIZE];pid_t pid;int sockfd[2], outSize, inSize;bool keepLooping;time (&now);keepLooping = true;cout << "Socket Pair test at " << ctime(&now);socketpair (AF_LOCAL, SOCK_STREAM, 0, sockfd);pid = fork() ;if (pid == 0) { // child process
while (keepLooping) {inSize = recv(sockfd[1], child_buf, LB_SIZE, 0);child_buf[inSize] = '\0';if (strncmp(child_buf, "bye", 3) == 0)
keepLooping = false;cout << "Child received: " << child_buf << endl;
}cout << "Closing child process" << endl;return 0;
} //end of child process section
sockpair.cpp
5
else if (pid > 0) { //parent processwhile (keepLooping) {
cout << "Enter text to send to child: " << endl;cin.getline(parent_buf, LB_SIZE);outSize = strlen(parent_buf);if (strncmp(parent_buf, "bye", 3) == 0)
keepLooping = false;send (sockfd[0], parent_buf, outSize, 0);
}cout << "Closing parent process..." << endl;return 0;
}}
sockpair example output
rcotter@kc-sce-450p2 sockpair]$ ./sockpair
Socket Pair test at Wed Oct 12 14:18:28 2011
Enter text to send to child:
This is the first message
Enter text to send to child:
Child received: This is the first message
This is the second message
Enter text to send to child:
Child received: This is the second message
bye
Closing parent process...
Child received: bye
Closing child process
[rcotter@kc-sce-450p2 sockpair]$6
Traditional UNIX Domain Sockets
• struct sockaddr_un {sa_family_t sun_family; //AF_LOCALchar sunpath[108]; //NULL terminated
path
• };
• sunpath length is 108 in Linux, but can be 104, 92, ? in other UNIX based systems.
• File (path name) must not exist (be linked) prior to bind( );
7
UNIX Domain socket created by bind
8
unix_udp_echos.cpp
9
#include <iostream>, <fstream>, <sys/socket.h>, <sys/types.h>#include <sys/un.h>, <string.h>, <unistd.h>using namespace std;#define MAXLINE 108void UDP_echo(int sockfd, sockaddr *pcliaddr, socklen_t clilen);
int main(int argc, char *argv[]){
int sockfd;struct sockaddr_un servaddr, cliaddr;char udp_path[MAXLINE];if (argc != 2) {
cout << "Usage: " << argv[0] << " socket_address " << endl;return(1);
}if (strlen(argv[1]) < MAXLINE)
strcpy(udp_path, argv[1]);else {
cout << "Socket Path name too long. Try again." << endl;return(1);
}
unix_udp_echos.cpp
10
sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
unlink(udp_path);bzero(&servaddr, sizeof(servaddr));servaddr.sun_family = AF_LOCAL;strcpy(servaddr.sun_path, udp_path);
bind(sockfd, (sockaddr *) &servaddr, sizeof(servaddr));
UDP_echo(sockfd, (sockaddr *) &cliaddr, sizeof(cliaddr));}
unix_udp_echos.cpp
11
void UDP_echo(int sockfd, sockaddr *pcliaddr, socklen_t clilen){
int n;socklen_t len;char mesg[MAXLINE];for ( ; ; ) {
memset(&mesg, 0, MAXLINE);len = clilen;n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);cout << "We just got " << n << " char: " << mesg << endl;sendto(sockfd, mesg, n, 0, pcliaddr, len);
}}
unix_udp_echo.cpp
12
#include <iostream>, <fstream>, <stdio.h>, <stdlib.h>, <sys/socket.h>#include <sys/types.h>, <sys/un.h>, <string.h>, <unistd.h>
using namespace std;#define MAXLINE 128void UDPecho(int sockfd, const sockaddr *pservaddr, socklen_t servlen);
int main(int argc, char *argv[]){
int sockfd;struct sockaddr_un cliaddr, servaddr;char udp_path[MAXLINE];if (argc != 2) {
cout << "Usage: " << argv[0] << " socket_address " << endl;return(1);
}if (strlen(argv[1]) < MAXLINE)
strcpy(udp_path, argv[1]);else {
cout << "Socket Path name too long. Try again." << endl;return(1);
}
unix_udp_echo.cpp
13
sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */cliaddr.sun_family = AF_LOCAL;// Bind the client to a local (unique but unnamed) filestrcpy(cliaddr.sun_path, tmpnam(NULL));bind(sockfd, (sockaddr *) &cliaddr, sizeof(cliaddr));//Identify the server’s address (file)bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */servaddr.sun_family = AF_LOCAL;strcpy(servaddr.sun_path, udp_path);
UDPecho(sockfd, (sockaddr *) &servaddr, sizeof(servaddr));close(sockfd);exit(0);
}
unix_udp_echo.cpp
14
void UDPecho(int sockfd, const sockaddr *pservaddr, socklen_t servlen){
int n;char sendline[MAXLINE], recvline[MAXLINE + 1];while (cin.getline(sendline, MAXLINE) != NULL) {
if (strncmp ("_bye", sendline, 4) == 0)break;
sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
recvline[n] = 0; /* null terminate */cout << recvline << endl;
}cout << "We jumped out of the loop" << endl;
}
UNIX Domain Sockets example
15
Summary
• socketpair( ) – Used to communicate between related processes.
– Works like a full-duplex pipe (called a stream pipe)
– Does not rely on transport layer functionality
• UNIX Domain Sockets– Used to communicate between UNIX / Linux processes
that have shared access to a socket file.• Can use file permissions to control access.
– Uses transport layer (TCP or UDP), but not network layer (IP)
• Removes IP / Ethernet packet size limitations (but still have transport layer limitations).
16