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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C++ SetTimer

    C++ SetTimer我搞了好久 最终也没成功的让SetTimer 回调一个非静态成员函数不过问题是解决了那就是把成员函数和要用到的那个成员变量换成静态了(有点拆东墙补西墙了)不过方法肯定是有的UINT_PTRSetTimer(HWNDhWnd,//窗口句柄UINT_PTRnIDEvent,//定时器ID,多个定时器

    2022年10月23日
    0
  • AutoSize

    AutoSizeLabel1->AutoSize=False;//TrueLabel1->Caption=”Thisstringistoolongtobethecaptionofthislabel”;通过为知笔记发布转载于:https://www.cnblogs.com/xe2011/archive/2012/06/03/5e3ea26bf00c3f837…

    2022年6月6日
    24
  • java基础—java中使用final关键字的总结

    有时候我,们希望某些东西是亘古不变的,可以使用final关键字完成这个重任!final学习总结:1:final + 属性如果属性是基本数据类型(byte 字节型short 短整型int 普通整型char 字符型float 浮点型long 长整型double 双精度),则变为常量,其值不能被更改;如果属性是引用类型,则引用地址不能被更改。(final 修饰一个对象,那么这个对象的引用地址

    2022年2月24日
    47
  • 循环队列的实现

    循环队列的实现

    2022年2月5日
    41
  • idea2021.11激活[最新免费获取]

    (idea2021.11激活)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~6EK6WKOHUX-eyJsaWNlbnNlSWQiOi…

    2022年3月28日
    49
  • pip和pip3的区别_linux将文件改为只读

    pip和pip3的区别_linux将文件改为只读前言装完python3后发现库里面既有pip也有pip3,不知道它们的区别,因此特意去了解了一下。解释先搜索了一下看到了如下的解释,安装了python3之后,库里面既会有pip3也会有pip1.

    2022年8月6日
    3

发表回复

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

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