非命名的UNIX域套接字
第1个参数domain,表示协议族,只能为AF_LOCAL或者AF_UNIX;
第2个参数type,表示类型,只能为0。
第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字对是管道流,与一般的管道相区别的是,套接字对建立的通道是双向的,即每一端都可以进行读写。不管是数据流还是数据报协议,unix域套接字都是可靠的,不丢包的。
第4个参数,用于保存建立的套接字对。
示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i_fd_arr[2];
int i_pid;
char psz_wbuf[16] = "0123456789";
char psz_rbuf[16] = {0};
if ( socketpair( AF_UNIX, SOCK_STREAM, 0, i_fd_arr ) < 0 )
{
perror( "socketpair" );
return -1;
}
if ( ( i_pid = fork() ) < 0 )
{
perror( "fork" );
return -1;
}
else if ( 0 == i_pid )
{
//child
close( i_fd_arr[0] );
if ( write( i_fd_arr[1], psz_wbuf, strlen( psz_wbuf ) ) < 0 )
{
perror( "write" );
exit( -1 );
}
memset( psz_rbuf, 0, sizeof( psz_rbuf ) );
if ( read( i_fd_arr[1], psz_rbuf, 16 ) < 0 )
{
perror( "read" );
exit( -1 );
}
printf( "child read: %s\n", psz_rbuf );
}
else
{
//parent
close( i_fd_arr[1] );
if ( read( i_fd_arr[0], psz_rbuf, 16 ) < 0 )
{
perror( "read" );
exit( -1 );
}
printf( "parent read: %s\n", psz_rbuf );
memset( psz_wbuf, 0, sizeof( psz_wbuf ) );
strncpy( psz_wbuf, "9876543210", sizeof( psz_wbuf ) - 1 );
if ( write( i_fd_arr[0], psz_wbuf, strlen( psz_wbuf ) ) < 0 )
{
perror( "write" );
exit( -1 );
}
}
return 0;
}
命名UNIX域套接字
TCP示例:
server.c
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int i_listenfd = 0, i_clientfd = 0;
struct sockaddr_un addr_server, addr_client;
char psz_path[32] = "./server_unixsocket_file";
int i_caddr_len = sizeof(struct sockaddr_un);
int i_saddr_len = sizeof(struct sockaddr_un);
char psz_rbuf[32] = {0};
char psz_wbuf[32] = "i am server.";
int i_readlen = 0;
//create a UNIX domain stream socket
if ( ( i_listenfd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
{
perror( "socket" );
return -1;
}
//in case it already exists
unlink( psz_path );
//fill in socket address structure
memset( &addr_server, 0, sizeof( addr_server ) );
addr_server.sun_family = AF_UNIX;
strncpy( addr_server.sun_path, psz_path, sizeof( addr_server.sun_path ) - 1 );
//bind the name to the descriptor
if ( bind( i_listenfd, ( struct sockaddr * )&addr_server, i_saddr_len ) < 0 )
{
perror( "bind" );
return -1;
}
if ( listen( i_listenfd, 10 ) < 0 )
{
perror( "listen" );
return -1;
}
while(1)
{
if ( ( i_clientfd = accept( i_listenfd, ( struct sockaddr * )&addr_client,
( socklen_t * )&i_caddr_len ) ) < 0 )
{
perror("accept");
return -1;
}
printf( "client is: %s\n", addr_client.sun_path );
if ( ( i_readlen = read( i_clientfd, psz_rbuf, sizeof( psz_rbuf ) - 1 ) ) < 0 )
{
perror( "read" );
return -1;
}
psz_rbuf[i_readlen] = '\0';
printf( "receive msg:%s\n", psz_rbuf );
if ( write( i_clientfd, psz_wbuf, strlen( psz_wbuf ) + 1 ) < 0 )
{
perror("write");
return -1;
}
}
unlink( psz_path );
return 0;
}
client.c
#include <stdio.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int i_fd = 0;
struct sockaddr_un addr;
char psz_path[32] = "./client_unixsocket_file";
char serverpath[32] = "./server_unixsocket_file";
int i_addr_len = sizeof( struct sockaddr_un );
char psz_wbuf[32] = "i am client.";
char psz_rbuf[32] = {0};
int i_readlen = 0;
if ( ( i_fd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
{
perror("socket");
return -1;
}
memset( &addr, 0, sizeof( addr ) );
addr.sun_family = AF_UNIX;
strncpy( addr.sun_path, psz_path, sizeof( addr.sun_path ) - 1 );
unlink( psz_path );
if ( bind( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 )
{
perror("bind");
return -1;
}
//fill socket adress structure with server's address
memset( &addr, 0, sizeof( addr ) );
addr.sun_family = AF_UNIX;
strncpy( addr.sun_path, serverpath, sizeof( addr.sun_path ) - 1 );
if ( connect( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 )
{
perror("connect");
return -1;
}
if ( write( i_fd, psz_wbuf, strlen( psz_wbuf ) + 1 ) < 0 )
{
perror( "write" );
return -1;
}
if ( ( i_readlen = read( i_fd, psz_rbuf, sizeof( psz_rbuf ) - 1 ) ) < 0 )
{
perror("write");
return -1;
}
psz_rbuf[i_readlen] = '\0';
printf( "receive msg:%s\n", psz_rbuf );
unlink( psz_path );
return -1;
}
UDP示例:
server
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int i_listenfd = 0/*, i_clientfd = 0*/;
struct sockaddr_un addr_server, addr_client;
char psz_path[32] = "./server_unixsocket_file";
int i_caddr_len = sizeof(struct sockaddr_un);
int i_saddr_len = 0;
char psz_rbuf[32] = {0};
char psz_wbuf[32] = "i am server.";
int i_readlen = 0;
//create a UNIX domain stream socket
if ( ( i_listenfd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
{
perror( "socket" );
return -1;
}
//in case it already exists
unlink( psz_path );
//fill in socket address structure
memset( &addr_server, 0, sizeof( addr_server ) );
addr_server.sun_family = AF_UNIX;
strncpy( addr_server.sun_path, psz_path, sizeof( addr_server.sun_path ) - 1 );
//bind the name to the descriptor
i_saddr_len = strlen( addr_server.sun_path ) + sizeof( addr_server.sun_family );
if ( bind( i_listenfd, ( struct sockaddr * )&addr_server, i_saddr_len ) < 0 )
{
perror( "bind" );
return -1;
}
while(1)
{
i_readlen = recvfrom( i_listenfd, psz_rbuf, sizeof( psz_rbuf ) - 1, 0,
( struct sockaddr * )&addr_client, ( socklen_t *)&i_caddr_len );
if ( i_readlen < 0 )
{
perror( "read" );
return -1;
}
printf( "client is: %s\n", addr_client.sun_path );
psz_rbuf[i_readlen] = '\0';
printf( "receive msg:%s\n", psz_rbuf );
if ( sendto( i_listenfd, psz_wbuf, strlen( psz_wbuf ) + 1, 0,
( struct sockaddr * )&addr_client, i_caddr_len ) < 0 )
{
perror( "write" );
return -1;
}
}
unlink( psz_path );
return 0;
}
Client
#include <stdio.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int i_fd = 0;
struct sockaddr_un addr;
char psz_clientpath[32] = "./client_unixsocket_file";
char psz_serverpath[32] = "./server_unixsocket_file";
int i_addr_len = 0;
char psz_wbuf[32] = "i am client.";
char psz_rbuf[32] = {0};
int i_readlen = 0;
if ( ( i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
{
perror("socket");
return -1;
}
memset( &addr, 0, sizeof( addr ) );
addr.sun_family = AF_UNIX;
strncpy( addr.sun_path, psz_clientpath, sizeof( addr.sun_path ) - 1 );
unlink( psz_clientpath );
i_addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
if ( bind( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 )
{
perror("bind");
return -1;
}
//fill socket adress structure with server's address
memset( &addr, 0, sizeof( addr ) );
addr.sun_family = AF_UNIX;
strncpy( addr.sun_path, psz_serverpath, sizeof( addr.sun_path ) - 1 );
i_addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
if ( sendto( i_fd, psz_wbuf, strlen( psz_wbuf ) + 1, 0,
( struct sockaddr * )&addr, i_addr_len ) < 0 )
{
perror( "write" );
return -1;
}
if ( ( i_readlen = recvfrom( i_fd, psz_rbuf, sizeof( psz_rbuf ) - 1, 0,
( struct sockaddr * )&addr, ( socklen_t * )&i_addr_len ) ) < 0 )
{
perror("write");
return -1;
}
psz_rbuf[i_readlen] = '\0';
printf( "receive msg:%s\n", psz_rbuf );
unlink( psz_clientpath );
return -1;
}
示例代码抄录自:https://blog.csdn.net/bytxl/article/details/47861469
用于加深理解