仅使用套接字实现单进程管道

虚空线

我想为单个进程实现pipe()内核调用,我也没有socketpair(),但是我可以使用非阻塞套接字。这是我现在拥有的:

#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <arpa/inet.h>

int main(void)
{
    // Wannabe server
    struct sockaddr_in addr;
    int fd;

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1)
    {
        printf("Error opening socket\n");
        return -1;
    }

    addr.sin_port = htons(0);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_family = AF_INET;

    if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
    {
        printf("Error binding socket\n");
        return -1;
    }

    if (fcntl(fd, F_SETFL, O_NONBLOCK))
    {
        printf("Unable to make socket non-blocking");
        return -1;
    }


    socklen_t socklen = sizeof(addr);
    getsockname(fd, &addr, &socklen);

    const uint16_t port = ntohs(addr.sin_port);
    printf("Successfully bound to port %u\n", ntohs(addr.sin_port));

    // Accept the data packet from client and verification
    struct sockaddr_in cli;
    size_t cli_size = sizeof(cli);

    accept(fd, &cli, &cli_size);



    // Wannabe client
    int sockfd;
    struct sockaddr_in servaddr;

    // socket create and varification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        return -1;
    }
    else
        printf("Socket successfully created..\n");
    memset(&servaddr, 0, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servaddr.sin_port = addr.sin_port;

    // connect the client socket to server socket
    if (connect(sockfd, &servaddr, sizeof(servaddr)) != 0)
        printf("connection with the server failed...\n");
    else
        printf("connected to the server..\n");

    return 0;
}

该程序说:

Successfully bound to port 44581
Socket successfully created..
connection with the server failed...

我的客户端套接字一定有问题,否则accept调用可能有问题。操作系统很奇怪,但是它是FreeBSD分支,它根本不支持进程调用。任何帮助将不胜感激!

戴夫M.

这可能会帮助您取得一些进步...我已经以非阻塞模式管理套接字/监听/接受+套接字/连接的内容。我有一个方向(服务器到客户端)的数据流,但显然客户端到服务器不是(我希望FD 5可读,但显然不能)。需要做更多的工作。

#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>

int
main( int argc, char **argv )
{
    // Wannabe server
    struct sockaddr_in addr;
    int fd;

    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        fprintf( stderr, "Error opening socket 1: %s\n", strerror( errno ) );
        return errno;
    }

    addr.sin_port = htons(0);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_family = AF_INET;

    if (bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1) {
        fprintf( stderr, "Error binding socket 1: %s\n", strerror( errno ) );
        return errno;
    }

    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
        fprintf( stderr, "Error setting NONBLOCK socket 1: %s\n", strerror( errno ) );
        return errno;
    }

    if (listen( fd, 5 )) {
        fprintf( stderr, "Error listening socket 1: %s\n", strerror( errno ) );
        return errno;
    }

    socklen_t socklen = sizeof(addr);
    getsockname(fd, (struct sockaddr *)&addr, &socklen);

    const uint16_t port = ntohs(addr.sin_port);
    printf( "Successfully bound to port %u\n", ntohs(addr.sin_port));

    struct sockaddr_in cli;
    socklen_t cli_size = sizeof(cli);

    errno = 0;

    int result;

    int srv2cli = accept( fd, (struct sockaddr *)&cli, &cli_size );

    printf( "Non-blocking accept() returns %d: %s\n", srv2cli, strerror( errno ) );


    // Wannabe client
    int sockfd;
    struct sockaddr_in servaddr;

    // socket create and varification
    if ((sockfd = socket( AF_INET, SOCK_STREAM, 0 )) == -1) {
        fprintf( stderr, "Error opening socket 2: %s\n", strerror( errno ) );
        return errno;
    }

    memset(&servaddr, 0, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servaddr.sin_port = addr.sin_port;

    if (fcntl( sockfd, F_SETFL, O_NONBLOCK)) {
        fprintf( stderr, "Error setting NONBLOCK socket 2: %s\n", strerror( errno ) );
        return errno;
    }

    errno = 0;
    result = connect( sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr) );

    printf( "Non-blocking connect() returns %d: %s\n", result, strerror( errno ) );

    for ( ; ; ) {
        fd_set  readfds;
        fd_set  writefds;
        fd_set  exceptfds;
        struct timeval   tv;

        int maxfd = fd;

        if (maxfd < sockfd) maxfd = sockfd;
        if (maxfd < srv2cli) maxfd = srv2cli;

        FD_ZERO( &readfds );
        FD_ZERO( &writefds );
        FD_ZERO( &exceptfds );

        FD_SET( fd, &readfds );
        FD_SET( fd, &writefds );
        FD_SET( fd, &exceptfds );

        FD_SET( sockfd, &readfds );
        FD_SET( sockfd, &writefds );
        FD_SET( sockfd, &exceptfds );

        if (srv2cli >= 0) {
            FD_SET( srv2cli, &readfds );
            FD_SET( srv2cli, &writefds );
            FD_SET( srv2cli, &exceptfds );
        }

        tv.tv_sec = 5;
        tv.tv_usec = 0;

        errno = 0;
        result = select( maxfd, &readfds, &writefds, &exceptfds, &tv );

        printf( "select returns %d : %s\n", result, strerror( errno ) );

        if (FD_ISSET( fd, &readfds )) {
            printf( "fd (%d) is ready to read (execute accept())\n", fd );
            srv2cli = accept( fd, (struct sockaddr *)&cli, &cli_size );
            printf( "\"Server\" accepted connection on fd %d (%s)\n", srv2cli, strerror( errno ) );
            if (fcntl( srv2cli, F_SETFL, O_NONBLOCK)) {
                fprintf( stderr, "Error setting NONBLOCK srv2cli socket : %s\n", strerror( errno ) );
                return errno;
            }
            result = write( srv2cli, "Hello, world", 12 );
            printf( "Transmitted %d bytes to client\n", result );
        }
        if (FD_ISSET( fd, &writefds )) printf( "fd (%d) is ready to write\n", fd );
        if (FD_ISSET( fd, &exceptfds )) printf( "fd (%d) is ready to except\n", fd );

        if (FD_ISSET( sockfd, &readfds )) {
            char buf[32];
            result = read( sockfd, buf, sizeof(buf) );
            printf( "sockfd(%d) is ready to read...got %d bytes\n", sockfd, result );
        }
        if (FD_ISSET( sockfd, &writefds )) {
            result = write( sockfd, "Foobar", 6 );
            printf( "sockfd (%d) is ready to write...sent %d bytes\n", sockfd, result );
        }
        if (FD_ISSET( sockfd, &exceptfds )) printf( "sockfd (%d) is ready to except\n", sockfd );

        if (FD_ISSET( srv2cli, &readfds )) printf( "srv2cli (%d) is ready to read\n", srv2cli );
        if (FD_ISSET( srv2cli, &writefds )) printf( "srv2cli (%d) is ready to write\n", srv2cli );
        if (FD_ISSET( srv2cli, &exceptfds )) printf( "srv2cli (%d) is ready to except\n", srv2cli );
    }

    return 0;
}

这将产生:

dhm@rubidium-debian:~/code/nettest$ ./a.out 2>&1 | head -20
Successfully bound to port 60219
Non-blocking accept() returns -1: Resource temporarily unavailable
Non-blocking connect() returns -1: Operation now in progress
select returns 1 : Success
fd (3) is ready to read (execute accept())
"Server" accepted connection on fd 5 (Success)
Transmitted 12 bytes to client
select returns 2 : Success
sockfd(4) is ready to read...got 12 bytes
sockfd (4) is ready to write...sent 6 bytes
select returns 1 : Success
sockfd (4) is ready to write...sent 6 bytes
select returns 1 : Success
sockfd (4) is ready to write...sent 6 bytes
select returns 1 : Success
sockfd (4) is ready to write...sent 6 bytes
select returns 1 : Success
sockfd (4) is ready to write...sent 6 bytes
select returns 1 : Success
sockfd (4) is ready to write...sent 6 bytes

(没有停止条件,因此您需要杀死它!)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

获取进程使用的套接字的IP地址

来自分类Dev

如何使用ZeroMQ实现多个套接字?

来自分类Dev

C POSIX进程管道/套接字通信练习第二个进程被卡住

来自分类Dev

将用户输入的主机添加到套接字,同时对套接字使用单例

来自分类Dev

Python套接字实现

来自分类Dev

使用Netcat将Unix套接字通过管道传输到TCP套接字

来自分类Dev

进程间通信使用哪种ZeroMQ套接字类型?

来自分类Dev

进程间通信使用哪种ZeroMQ套接字类型?

来自分类Dev

如何在Python和子进程中使用套接字?

来自分类Dev

时间同步,使用NTP还是仅使用套接字?

来自分类Dev

如何使用快速游乐场实现套接字连接?

来自分类Dev

如何使用系统默认套接字实现SocketImplFactory

来自分类Dev

如何使用系统默认套接字实现SocketImplFactory

来自分类Dev

使用套接字的C ++ FTP PORT命令实现

来自分类Dev

如何使用套接字安全地实现通知系统?

来自分类Dev

仅使用套接字的Python中的Mail Client(无smtplib)

来自分类Dev

scapy 中的套接字实现

来自分类Dev

如何使用 spring-integration 创建异步单例套接字服务器?

来自分类Dev

在子进程中关闭打开的套接字

来自分类Dev

将套接字传递给子进程

来自分类Dev

与不带套接字的rsync守护进程通信

来自分类Dev

使用套接字的IllegalBlockingModeException

来自分类Dev

通过多个套接字传输文件比仅使用一个套接字传输文件快吗?

来自分类Dev

在另一个进程已经使用的套接字中使用“ t”

来自分类Dev

在阻塞管道或套接字上是否可以使用select()+ non-blocking write()?

来自分类Dev

使用命名管道和套接字而不是临时文件的优点

来自分类Dev

如何在Python中使用管道时关闭套接字连接

来自分类Dev

与根,打开其他进程套接字并使用python获取tcp_info?

来自分类Dev

使用共享内存在两个进程之间传递套接字描述符

Related 相关文章

  1. 1

    获取进程使用的套接字的IP地址

  2. 2

    如何使用ZeroMQ实现多个套接字?

  3. 3

    C POSIX进程管道/套接字通信练习第二个进程被卡住

  4. 4

    将用户输入的主机添加到套接字,同时对套接字使用单例

  5. 5

    Python套接字实现

  6. 6

    使用Netcat将Unix套接字通过管道传输到TCP套接字

  7. 7

    进程间通信使用哪种ZeroMQ套接字类型?

  8. 8

    进程间通信使用哪种ZeroMQ套接字类型?

  9. 9

    如何在Python和子进程中使用套接字?

  10. 10

    时间同步,使用NTP还是仅使用套接字?

  11. 11

    如何使用快速游乐场实现套接字连接?

  12. 12

    如何使用系统默认套接字实现SocketImplFactory

  13. 13

    如何使用系统默认套接字实现SocketImplFactory

  14. 14

    使用套接字的C ++ FTP PORT命令实现

  15. 15

    如何使用套接字安全地实现通知系统?

  16. 16

    仅使用套接字的Python中的Mail Client(无smtplib)

  17. 17

    scapy 中的套接字实现

  18. 18

    如何使用 spring-integration 创建异步单例套接字服务器?

  19. 19

    在子进程中关闭打开的套接字

  20. 20

    将套接字传递给子进程

  21. 21

    与不带套接字的rsync守护进程通信

  22. 22

    使用套接字的IllegalBlockingModeException

  23. 23

    通过多个套接字传输文件比仅使用一个套接字传输文件快吗?

  24. 24

    在另一个进程已经使用的套接字中使用“ t”

  25. 25

    在阻塞管道或套接字上是否可以使用select()+ non-blocking write()?

  26. 26

    使用命名管道和套接字而不是临时文件的优点

  27. 27

    如何在Python中使用管道时关闭套接字连接

  28. 28

    与根,打开其他进程套接字并使用python获取tcp_info?

  29. 29

    使用共享内存在两个进程之间传递套接字描述符

热门标签

归档