前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >socket常用函数_socket是可重入函数吗

socket常用函数_socket是可重入函数吗

作者头像
全栈程序员站长
发布2022-11-04 14:48:35
3630
发布2022-11-04 14:48:35
举报
文章被收录于专栏:全栈程序员必看

前言

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档