16
UNIX Domain sockets The Linux Programming Interface (ch 57) UNIX Network Programming – Vol 1, 3ed (ch 15)

UNIX Domain sockets

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

Page 1: UNIX Domain sockets

UNIX Domain sockets

The Linux Programming Interface

(ch 57)

UNIX Network Programming – Vol 1, 3ed (ch 15)

Page 2: UNIX Domain sockets

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

Page 3: UNIX Domain sockets

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

Page 4: UNIX Domain sockets

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

Page 5: UNIX Domain sockets

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;

}}

Page 6: UNIX Domain sockets

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

Page 7: UNIX Domain sockets

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

Page 8: UNIX Domain sockets

UNIX Domain socket created by bind

8

Page 9: UNIX Domain sockets

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

}

Page 10: UNIX Domain sockets

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

Page 11: UNIX Domain sockets

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

}}

Page 12: UNIX Domain sockets

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

}

Page 13: UNIX Domain sockets

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

}

Page 14: UNIX Domain sockets

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;

}

Page 15: UNIX Domain sockets

UNIX Domain Sockets example

15

Page 16: UNIX Domain sockets

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