socket同样可以用于本地通信创建套接字时使用本地协议PF_UNIX(或PF_LOCAL)分为流式套接字和用户数据报套接字,区别还是有无连接常用于前后台进程通信。
使用的机构体
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[108];
};
1.2TCP本地通信流程
服务器:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
将套接字与服务器本地信息结构体绑定 bind( )
将套接字设置为被动监听状态 listen( )
阻塞等待客户端的连接请求 accept( )
进行通信 recv( )/send( ) 或 read( )/write( )
客户端:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
发送客户端的连接请求 connect( )
进行通信 send( )/recv( )
1.3代码实现代码说明:这就是一个循环应答的一个代码,来讲解本地通信
服务器代码#include客户端#include #include #include #include #include #include #include #define ERRLOG(errmsg) do{ printf("%s:%s:%d --", __FILE__, __func__, __LINE__); perror(errmsg); exit(-1); }while(0) int main(int argc, const char *argv[]){ if(2 != argc){ printf("Usage : %s n", argv[0]); return -1; } //创建流式套接字 int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if(-1 == sockfd){ ERRLOG("socket error"); } //填充信息本地信息结构体 struct sockaddr_un serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sun_family = AF_UNIX; strcpy(serveraddr.sun_path, argv[1]); socklen_t serveraddr_len = sizeof(serveraddr); //绑定 if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){ ERRLOG("bind error"); } //监听 if(-1 == listen(sockfd, 5)){ ERRLOG("listen error"); } //定义结构体保存对方的信息 struct sockaddr_un clientaddr; memset(&clientaddr, 0, sizeof(clientaddr)); socklen_t clientaddr_len = sizeof(clientaddr); int acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len); if(-1 == acceptfd){ ERRLOG("accept error"); } printf("客户端[%s]连接到服务器n", clientaddr.sun_path); char buff[128] = {0}; while(1){ if(-1 == recv(acceptfd, buff, 128, 0)){ ERRLOG("recv error"); } printf("客户端[%s]发来数据[%s]n", clientaddr.sun_path, buff); strcat(buff, "--hqyj"); if(-1 == send(acceptfd, buff, 128, 0)){ ERRLOG("send error"); } memset(buff, 0, 128); } close(acceptfd); close(sockfd); return 0; }
#include二UDP本地通信 2.1流程#include #include #include #include #include #include #include #define ERRLOG(errmsg) do{ printf("%s:%s:%d --", __FILE__, __func__, __LINE__); perror(errmsg); exit(-1); }while(0) int main(int argc, const char *argv[]){ if(2 != argc){ printf("Usage : %s n", argv[0]); return -1; } //创建流式套接字 int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if(-1 == sockfd){ ERRLOG("socket error"); } //填充服务器本地信息结构体 struct sockaddr_un serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sun_family = AF_UNIX; strcpy(serveraddr.sun_path, argv[1]); socklen_t serveraddr_len = sizeof(serveraddr); //定义客户端本地信息结构体 struct sockaddr_un clientaddr; memset(&clientaddr, 0, sizeof(clientaddr)); clientaddr.sun_family = AF_UNIX; strcpy(clientaddr.sun_path,"tcp_client_file"); socklen_t clientaddr_len = sizeof(clientaddr); //客户端需要绑定,否则服务器收不到客户端的文件名 if(-1 == bind(sockfd, (struct sockaddr *)&clientaddr, clientaddr_len)){ ERRLOG("bind error"); } if(-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){ ERRLOG("accept error"); } printf("连接服务器成功n"); char buff[128] = {0}; while(1){ fgets(buff, 128, stdin); buff[strlen(buff)-1] = ' '; if(-1 == send(sockfd, buff, 128, 0)){ ERRLOG("send error"); } if(-1 == recv(sockfd, buff, 128, 0)){ ERRLOG("recv error"); } printf("应答[%s]n", buff); memset(buff, 0, 128); } close(sockfd); return 0; }
服务器:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
将套接字与服务器本地信息结构体绑定 bind( )
进行通信 recvfrom( ) / sendto( )
客户端:
创建套接字 socket( )
填充客户端本地信息结构体 sockaddr_un
将套接字与客户端本地信息结构体绑定 bind()
填充服务器本地信息结构体 sockaddr_un
进行通信 sendto( ) / recvfrom( )
2.2代码实现 服务器#include客户端#include #include #include #include #include #include #include #define ERRLOG(errmsg) do{ printf("%s:%s:%d --", __FILE__, __func__, __LINE__); perror(errmsg); exit(-1); }while(0) int main(int argc, const char *argv[]){ if(2 != argc){ printf("Usage : %s n", argv[0]); return -1; } //创建用户数据报套接字 int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0); if(-1 == sockfd){ ERRLOG("socket error"); } //填充服务器信息本地信息结构体 struct sockaddr_un serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sun_family = AF_UNIX; strcpy(serveraddr.sun_path, argv[1]); socklen_t serveraddr_len = sizeof(serveraddr); //绑定 if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){ ERRLOG("bind error"); } //定义结构体保存对方的信息 struct sockaddr_un clientaddr; memset(&clientaddr, 0, sizeof(clientaddr)); socklen_t clientaddr_len = sizeof(clientaddr); char buff[128] = {0}; while(1){ if(-1 == recvfrom(sockfd, buff, 128, 0, (struct sockaddr *)&clientaddr, &clientaddr_len)){ ERRLOG("recv error"); } printf("客户端[%s]发来数据[%s]n", clientaddr.sun_path, buff); strcat(buff, "--hqyj"); if(-1 == sendto(sockfd, buff, 128, 0, (struct sockaddr *)&clientaddr, clientaddr_len)){ ERRLOG("send error"); } memset(buff, 0, 128); } close(sockfd); return 0; }
#include#include #include #include #include #include #include #include #define ERRLOG(errmsg) do{ printf("%s:%s:%d --", __FILE__, __func__, __LINE__); perror(errmsg); exit(-1); }while(0) int main(int argc, const char *argv[]){ if(3 != argc){ printf("Usage : %s n", argv[0]); return -1; } //创建用户数据报套接字 int sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0); if(-1 == sockfd){ ERRLOG("socket error"); } //填充服务器本地信息结构体 struct sockaddr_un serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sun_family = AF_UNIX; strcpy(serveraddr.sun_path, argv[1]); socklen_t serveraddr_len = sizeof(serveraddr); //定义客户端本地信息结构体 struct sockaddr_un clientaddr; memset(&clientaddr, 0, sizeof(clientaddr)); clientaddr.sun_family = AF_UNIX; strcpy(clientaddr.sun_path, argv[2]); socklen_t clientaddr_len = sizeof(clientaddr); //客户端需要绑定,否则服务器收不到客户端的文件名 if(-1 == bind(sockfd, (struct sockaddr *)&clientaddr, clientaddr_len)){ ERRLOG("bind error"); } char buff[128] = {0}; while(1){ fgets(buff, 128, stdin); buff[strlen(buff)-1] = ' '; if(-1 == sendto(sockfd, buff, 128, 0, (struct sockaddr *)&serveraddr, serveraddr_len)){ ERRLOG("send error"); } //因为serveraddr没有变过 所以无需再保存了 if(-1 == recvfrom(sockfd, buff, 128, 0, NULL, NULL)){ ERRLOG("recv error"); } printf("应答[%s]n", buff); memset(buff, 0, 128); } close(sockfd); return 0; }



