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


相关推荐

  • 用python浪漫告白_python动态心形代码

    用python浪漫告白_python动态心形代码Python是一种面向他人进行的说明型编程方法,其源代码与说明器CPython遵守GPL协议,语法简洁清晰。那么,我们用少量的Python代码能做哪些有趣的东西?让小编告诉你。一、编写浪漫的心型1、图形都是由一系列的点(X,Y)构成的曲线,由于X,Y满足一定的关系,所以我们就可以建立模型,建立表达式expression,当关系满足时,两个for循环(forXinrange;forYin…

    2022年9月24日
    0
  • 记录使用Depix过程(小白文)

    记录使用Depix过程(小白文)Tips:本文仅用做探索记录(外行+新手),不保证正确性,慎读慎参考!背景:无聊看到一个可以去除马赛克的工具,并有GitHub源码(短短几天10K+star,lsp警告????,我反正不是,没跑过Python代码,一次尝试而已)。过程为本人第一视角,漏掉的部分请自行探索。下载源码,cd到根目录,执行文档(README.d)中的Example代码。到这里,目前还不明白这行代码的意思,不过可以看到两个图片路径,都在示例代码中出现,最后一个看名字就知道,工程根目录输出一个output.png图片。猜测为执

    2022年6月29日
    117
  • FTP协议是一种用于什么的协议

    FTP协议是一种用于什么的协议FTP协议是一种用于什么的协议FTP(FileTransferProtocol,文件传输协议)是TCP/IP协议组中的协议之一。复FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。在开发网站的时候,通常利用FTP协议把网页或程序传制到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。扩展资料FTP协议的任务从一台计算机.

    2022年6月16日
    38
  • windows配置java环境[通俗易懂]

    windows配置java环境的方法是:1、首先进入高级系统设置选项,点击【环境变量】;2、接着点击【系统变量】下的【新建】;3、然后新建【JAVA_HOME】、【classpath】变量;4、编辑【Path】变量;5、最后进行测试即可。

    2022年1月16日
    60
  • js判断是否包含指定字符串_js正则表达式匹配字符串

    js判断是否包含指定字符串_js正则表达式匹配字符串前言:有时候,我们在js中需要判断一个字符串中,是不是包含某个字符。可以采用以下方法进行判断。String对象的方法方法一:indexOf()(推荐)varstr=”123″;console.log(str.indexOf(“3”)!=-1);//trueindexOf()方法可返回某个指定的字符串值,在首次出现的位置。如果要检索的字符串值没有出现,则改方法返回-1。方法二:search()…

    2022年10月7日
    1
  • Android Studio安装教程(超级详细)「建议收藏」

    Android Studio安装教程(超级详细)「建议收藏」AndroidStudio安装教程(超级详细)欢迎使用Markdown编辑器获取AndroidStudio安装AndroidStudio欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Markdown编辑器,可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。获取AndroidStudio安装前提(系统安装了jdk,并且版本在1.8以上)官网下载AndroidDevTools下载AndroidStudio

    2022年7月15日
    12

发表回复

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

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