前言
socketpair是Linux下的函数,其主要作用是创建一对套节字来进行进程间通信,其与匿名管道(PIPE)的作用相似,这两个套节字均可读可写. 具体介绍见本博客另一篇文章: https://blog.csdn.net/wufuhuai/article/details/79747912
实现
我们都知道socket不仅能够进行跨进程通信, 而且socket是可以双向通信的, 即是可读可写的; 故本文主要设计思想是创建两个回环的socket进行进程间通信, 即创建两个socket进行本机跟本机间通信.
代码语言:javascript复制#include <stdlib.h>
#include <stdio.h>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
static int __stream_socketpair(struct addrinfo* addr_info, SOCKET sock[2]){
SOCKET listener, client, server;
int opt = 1;
listener = server = client = INVALID_SOCKET;
listener = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol); //创建服务器socket并进行绑定监听等
if (INVALID_SOCKET == listener)
goto fail;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,(const char*)&opt, sizeof(opt));
if(SOCKET_ERROR == bind(listener, addr_info->ai_addr, addr_info->ai_addrlen))
goto fail;
if (SOCKET_ERROR == getsockname(listener, addr_info->ai_addr, (int*)&addr_info->ai_addrlen))
goto fail;
if(SOCKET_ERROR == listen(listener, 5))
goto fail;
client = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol); //创建客户端socket,并连接服务器
if (INVALID_SOCKET == client)
goto fail;
if (SOCKET_ERROR == connect(client,addr_info->ai_addr,addr_info->ai_addrlen))
goto fail;
server = accept(listener, 0, 0);
if (INVALID_SOCKET == server)
goto fail;
closesocket(listener);
sock[0] = client;
sock[1] = server;
return 0;
fail:
if(INVALID_SOCKET!=listener)
closesocket(listener);
if (INVALID_SOCKET!=client)
closesocket(client);
return -1;
}
static int __dgram_socketpair(struct addrinfo* addr_info,SOCKET sock[2])
{
SOCKET client, server;
struct addrinfo addr, *result = NULL;
const char* address;
int opt = 1;
server = client = INVALID_SOCKET;
server = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (INVALID_SOCKET == server)
goto fail;
setsockopt(server, SOL_SOCKET,SO_REUSEADDR, (const char*)&opt, sizeof(opt));
if(SOCKET_ERROR == bind(server, addr_info->ai_addr, addr_info->ai_addrlen))
goto fail;
if (SOCKET_ERROR == getsockname(server, addr_info->ai_addr, (int*)&addr_info->ai_addrlen))
goto fail;
client = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (INVALID_SOCKET == client)
goto fail;
memset(&addr,0,sizeof(addr));
addr.ai_family = addr_info->ai_family;
addr.ai_socktype = addr_info->ai_socktype;
addr.ai_protocol = addr_info->ai_protocol;
if (AF_INET6==addr.ai_family)
address = "0:0:0:0:0:0:0:1";
else
address = "127.0.0.1";
if (getaddrinfo(address, "0", &addr, &result))
goto fail;
setsockopt(client,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt, sizeof(opt));
if(SOCKET_ERROR == bind(client, result->ai_addr, result->ai_addrlen))
goto fail;
if (SOCKET_ERROR == getsockname(client, result->ai_addr, (int*)&result->ai_addrlen))
goto fail;
if (SOCKET_ERROR == connect(server, result->ai_addr, result->ai_addrlen))
goto fail;
if (SOCKET_ERROR == connect(client, addr_info->ai_addr, addr_info->ai_addrlen))
goto fail;
freeaddrinfo(result);
sock[0] = client;
sock[1] = server;
return 0;
fail:
if (INVALID_SOCKET!=client)
closesocket(client);
if (INVALID_SOCKET!=server)
closesocket(server);
if (result)
freeaddrinfo(result);
return -1;
}
int socketpair(int family, int type, int protocol,SOCKET recv[2]){
const char* address;
struct addrinfo addr_info,*p_addrinfo;
int result = -1;
memset(&addr_info, 0, sizeof(addr_info));
addr_info.ai_family = family;
addr_info.ai_socktype = type;
addr_info.ai_protocol = protocol;
if (AF_INET6==family)
address = "0:0:0:0:0:0:0:1";
else
address = "127.0.0.1";
if (0 == getaddrinfo(address, "0", &addr_info, &p_addrinfo)){
if (SOCK_STREAM == type)
result = __stream_socketpair(p_addrinfo, recv); //use for tcp
else if(SOCK_DGRAM == type)
result = __dgram_socketpair(p_addrinfo, recv); //use for udp
freeaddrinfo(p_addrinfo);
}
return result;
}
int main ()
{
int recv_pair[2]; /* A socket pair to unblock select, when needed */
WSADATA wsaData;
WORD socketVersion = MAKEWORD(2,0);
if (WSAStartup(socketVersion, &wsaData) != 0)
{
printf("Init socket dll err");
}
if(socketpair(AF_INET, SOCK_STREAM, 0, recv_pair) < 0)
printf("Error setting Socket pair...");
WSACleanup();
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/182174.html原文链接:https://javaforall.cn