UNIX Domain sockets

Download Report

Transcript UNIX Domain sockets

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 • 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

#define LB_SIZE 128 int 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 4

sockpair.cpp

} else if (pid > 0) { //parent process while (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; } 5

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_LOCAL char 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 Sockets example

8

Traditional UNIX Domain Sockets

Server Socket mytemp.txt

Client Socket “unnamed” 9

UNIX Domain socket created by bind

10

unix_udp_echos.cpp

#include , , , #include , , using namespace std; #define MAXLINE 108 void 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); } 11

unix_udp_echos.cpp

} 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)); 12

unix_udp_echos.cpp

void UDP_echo(int sockfd, sockaddr *pcliaddr, socklen_t clilen) { int socklen_t len; n; char for ( ; ; ) { mesg[MAXLINE]; 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);

} } 13

unix_udp_echo.cpp

#include , , , , #include , , , using namespace std; #define MAXLINE 128 void 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); } 14

unix_udp_echo.cpp

} sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0); bzero(&cliaddr, sizeof(cliaddr)); cliaddr.sun_family = AF_LOCAL; /* bind an address for us */ // Bind the client to a local (unique but unnamed) file

strcpy(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); 15

unix_udp_echo.cpp

void UDPecho(int sockfd, const sockaddr *pservaddr, socklen_t servlen) { int char n; 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; } 16

UNIX Domain Sockets example

17

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).

18