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

socket常用函数_socket是可重入函数吗前言socketpair是Linux下的函数,其主要作用是创建一对套节字来进行进程间通信,其与匿名管道(PIPE)的作用相似,这两个套节字均可读可写.具体介绍见本博客另一篇文章:https://blog.csdn.net/wufuhuai/article/details/79747912实现我们都知道socket不仅能够进行跨进程通信,而且socket是可以双向通信的,即是…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

前言

socketpair是Linux下的函数,其主要作用是创建一对套节字来进行进程间通信,其与匿名管道(PIPE)的作用相似,这两个套节字均可读可写. 具体介绍见本博客另一篇文章: https://blog.csdn.net/wufuhuai/article/details/79747912

实现

我们都知道socket不仅能够进行跨进程通信, 而且socket是可以双向通信的, 即是可读可写的; 故本文主要设计思想是创建两个回环的socket进行进程间通信, 即创建两个socket进行本机跟本机间通信.

#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.net/182174.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux安装Promethus普罗米修斯监控

    linux安装Promethus普罗米修斯监控普罗米修斯Prometheus

    2022年7月19日
    23
  • sql server 安装_安装wsl

    sql server 安装_安装wslPython2.7.7源码安装注意:1.同时安装相对应的numpy,pip,easy_install(注意不是系统自带的python2.6的pip或者easy_install)。2.原来的python不能删除,否则yum无法使用3.安装结束后测试yum能否使用教程链接:https://github.com/0xdata/h2o/wiki/Installing-p

    2025年7月17日
    5
  • 杂谈 – 自定义搜索引擎

    杂谈 – 自定义搜索引擎在Firefox上,以{肯定被驳回}搜索引擎为例。{肯定被驳回}搜索引擎搜索英文关键词时,给出的也基本是英文,例如这样:看了几篇不符合自己的胃口,遂点击了左上角小提示:仅限简体中文结果,例如这样:发现第二篇就是自己想要的东西,遂想,中文的结果也不错,何不设置不管中英文关键字,都先输出中文呢?所以实现方式,就是:添加addcustomsearchengine。2.点击扩展图标其中,SearchURL为:为了避免被驳回,请自行输入。然后点击蓝色按钮。然后在Firefox的

    2022年7月13日
    20
  • Apache Ant安装与配置

    Apache Ant安装与配置下载ApacheAnt1.8.4http://ant.apache.org/bindownload.cgi一、解压ant安装包在D:\SWE下二、环境变量配置ANT_HOMED:\SWE\apache-ant-1.8.4CLASSPATH;%ANT_HOME%lib;PATH  ;%ANT_HOME%bin;三、测试是否安装成功在cm

    2022年7月24日
    8
  • javaweb注册登录案例(thinkphp注册登录源码)

    一、Servlet+JSP+JavaBean开发模式(MVC)介绍  Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。Servlet+JSP+JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。  这里以一个最常用的用户登录注册程序来讲解Servl…

    2022年4月16日
    65
  • Ubuntu 20.04 搭建OpenStack Yoga(allinone)

    Ubuntu 20.04 搭建OpenStack Yoga(allinone)文章目录环境准备换源网络配置静态IP桥接永久修改DNS主机名基础服务数据库etcdmemcachedOpenStackNova很多文章都是devstack安装的allinone,我这里使用源码组件手动安装。环境准备这里需要先配置一些环境。首先我这里是虚拟机安装的系统,可能设置的密码不是当前用户的root密码,反正就得重置一下执行下面的命令,然后输入安装系统设置的密码,之后就可以了。sudopasswdroot换源需要先换一个源,方便下载换阿里源gedit/etc/apt/sourc

    2025年7月1日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号