// gcc testBipollar.c -lrdmacm -lpthread -o testBipollar #include #include #include #include #include #include #include #include // remove leading `r` to use regular TCP sockets #define SOCKET rsocket #define BIND rbind #define LISTEN rlisten #define ACCEPT raccept #define GETSOCKNAME rgetsockname #define CONNECT rconnect #define POLL rpoll #define FCNTL rfcntl static const char* hostname = "10.0.2.15"; // << INSERT YOUR IP HERE static int lrs, rs; void *accepting_side_function(void *ptr); void *polling_side_function(void *ptr); int main() { int ret, port; pthread_t thread1, thread2; struct sockaddr_in addr, addr2; socklen_t addr_len = sizeof(addr); lrs = SOCKET(AF_INET, SOCK_STREAM, 0); if (lrs < 0) perror("rsocket; lrs"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); ret = BIND(lrs, (struct sockaddr *) &addr, addr_len); if (ret < 0) perror("rbind: lrs"); ret = LISTEN(lrs, 10); if (ret < 0) perror("rlisten: lrs"); memset(&addr, 0, sizeof(addr)); if (GETSOCKNAME(lrs, (struct sockaddr *) &addr, &addr_len) < 0) perror("rgetsockname"); port = addr.sin_port; fprintf(stdout, "\nlistening on port %d", ntohs(port)); // Start the accepting-side thread pthread_create(&thread1, NULL, accepting_side_function, (void*) NULL); rs = SOCKET(AF_INET, SOCK_STREAM, 0); if (rs < 0) perror("rsocket: rs"); // Configure the connecting socket to be non-blocking FCNTL(rs, F_SETFL, (FCNTL(rs, F_GETFL) | O_NONBLOCK)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = port; ret = inet_aton(hostname, &addr.sin_addr); if (ret < 0) perror("inet_aton"); fprintf(stdout, "\nconnecting to %s:%d \n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); ret = CONNECT(rs, (struct sockaddr *)&addr, sizeof(struct sockaddr)); if (ret >= 0) { fprintf(stdout, "\nconnected immediately"); } else if (errno == EAGAIN || errno == EWOULDBLOCK) { perror("rconnect: rs"); exit(4); } else { fprintf(stdout, "\nconnect not completed, polling ..."); pthread_create(&thread1, NULL, polling_side_function, (void*) NULL); pthread_create(&thread2, NULL, polling_side_function, (void*) NULL); pthread_join(thread1, NULL); pthread_join(thread2, NULL); fprintf(stdout, "\npolling threads completed"); } } void *accepting_side_function(void *ptr) { struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); int ret; fprintf(stdout, "\naccepted... "); ret = ACCEPT(lrs, (struct sockaddr *)&addr, &addr_len); if (ret >= 0) { fprintf(stdout, "\naccepted new connection: %d ", ret); } else { perror("raccept: lrs"); exit(1); } } void *polling_side_function(void *ptr) { int ret; struct pollfd pfd; pfd.fd = rs; pfd.events = POLLOUT; fprintf(stdout, "\npolling: fd:[%d] ", pfd.fd); ret = POLL(&pfd, 1, -1); if (ret < 0) { perror("rpoll: rs"); exit(7); } fprintf(stdout, "\npolling returned [%d]", ret); }