coroutine void collect(chan workers, int back_router) { //int back_router = nn_socket(AF_SP_RAW, NN_REP); //nn_bind(back_router, BACKROUTER); int ready; size_t ready_sz = sizeof (ready); nn_getsockopt(back_router, NN_SOL_SOCKET, NN_RCVFD, &ready, &ready_sz); struct nn_msghdr hdr; char *body = malloc(sizeof(char)*128); while(1){ char *ctrl = malloc(sizeof(char)*64); memset(&hdr, 0, sizeof(hdr)); struct nn_iovec iovec; iovec.iov_base = body; iovec.iov_len = 128; hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = ctrl; hdr.msg_controllen = 64; fdwait(ready, FDW_IN, -1); int rc = nn_recvmsg(back_router, &hdr, NN_DONTWAIT); printf("%.*s\n", hdr.msg_iov->iov_len, (char*) hdr.msg_iov->iov_base); chs(workers, char*, ctrl); } }
int ftw_nanomsg_router_recv (int router_id, void *incoming_msg_body, size_t *incoming_body_size, void *incoming_msg_header, size_t *incoming_header_size, int timeout) { struct nn_iovec iov; struct nn_msghdr hdr; int rc; iov.iov_base = incoming_msg_body; iov.iov_len = NN_MSG; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = incoming_msg_header; hdr.msg_controllen = NN_MSG; nn_setsockopt(router_id, NN_SOL_SOCKET, NN_RCVTIMEO, &timeout, sizeof(timeout)); rc = nn_recvmsg (router_id, &hdr, NN_NOFLAGS); if (rc < 0) { rc = nn_errno(); return rc; } else { *incoming_body_size = rc; *incoming_header_size = hdr.msg_controllen; return 0; } }
void receive_ctxt(int socket, const FHEPubKey &pk, std::vector<Ctxt> &ctxts) { std::stringstream sstream; MDL::Timer timer; char *buf; nn_recv(socket, &buf, NN_MSG, 0); // recv lens nn_send(socket, NULL, 0, 0); // send ok MDL::net::msg_header *hdr = (MDL::net::msg_header *)buf; std::vector<size_t> lens(hdr->msg_ele_sze, hdr->msg_ele_sze + hdr->msg_ele_nr); printf("vec size %zd\n", lens.size()); timer.start(); struct nn_msghdr nn_hdr; MDL::net::make_nn_header(&nn_hdr, lens); printf("%zd\n", nn_hdr.msg_iovlen); nn_recvmsg(socket, &nn_hdr, 0); // recv data timer.end(); Ctxt c(pk); for (size_t i = 0; i < nn_hdr.msg_iovlen; i++) { sstream.str((char *)nn_hdr.msg_iov[i].iov_base); sstream >> c; ctxts.push_back(c); } nn_freemsg(buf); nn_send(socket, NULL, 0, 0); printf("receive %zd ciphers %fs\n", ctxts.size(), timer.second()); }
int nn_device_mvmsg (struct nn_device_recipe *device, int from, int to, int flags) { int rc; void *body; void *control; struct nn_iovec iov; struct nn_msghdr hdr; iov.iov_base = &body; iov.iov_len = NN_MSG; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = &control; hdr.msg_controllen = NN_MSG; rc = nn_recvmsg (from, &hdr, flags); if (nn_slow (rc < 0 && nn_errno () == ETERM)) return -1; errno_assert (rc >= 0); rc = device->nn_device_rewritemsg(device,from,to,flags,&hdr,rc); if (nn_slow(rc==-1)) return -1; else if (rc==0) return 0; nn_assert(rc==1); rc = nn_sendmsg (to, &hdr, flags); if (nn_slow (rc < 0 && nn_errno () == ETERM)) return -1; errno_assert (rc >= 0); return 0; }
inline int recvmsg (struct nn_msghdr *msghdr, int flags) { int rc = nn_recvmsg (s, msghdr, flags); if (nn_slow (rc < 0)) { if (nn_slow (nn_errno () != EAGAIN)) throw nn::exception (); return -1; } return rc; }
int nn_recv (int s, void *buf, size_t len, int flags) { struct nn_iovec iov; struct nn_msghdr hdr; iov.iov_base = buf; iov.iov_len = len; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = NULL; hdr.msg_controllen = 0; return nn_recvmsg (s, &hdr, flags); }
int main () { int rc; int sb; int sc; struct nn_iovec iov [2]; struct nn_msghdr hdr; char buf [6]; sb = nn_socket (AF_SP, NN_PAIR); errno_assert (sb != -1); rc = nn_bind (sb, SOCKET_ADDRESS); errno_assert (rc >= 0); sc = nn_socket (AF_SP, NN_PAIR); errno_assert (sc != -1); rc = nn_connect (sc, SOCKET_ADDRESS); errno_assert (rc >= 0); iov [0].iov_base = "AB"; iov [0].iov_len = 2; iov [1].iov_base = "CDEF"; iov [1].iov_len = 4; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = iov; hdr.msg_iovlen = 2; rc = nn_sendmsg (sc, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 6); iov [0].iov_base = buf; iov [0].iov_len = 4; iov [1].iov_base = buf + 4; iov [1].iov_len = 2; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = iov; hdr.msg_iovlen = 2; rc = nn_recvmsg (sb, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 6); nn_assert (memcmp (buf, "ABCDEF", 6) == 0); rc = nn_close (sc); errno_assert (rc == 0); rc = nn_close (sb); errno_assert (rc == 0); return 0; }
int ftw_nanomsg_recv (int s, void *buf, size_t length, int timeout, int flags) { struct nn_iovec iov; struct nn_msghdr hdr; iov.iov_base = buf; iov.iov_len = NN_MSG; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = NULL; hdr.msg_controllen = 0; nn_setsockopt(s, NN_SOL_SOCKET, NN_RCVTIMEO, &timeout, sizeof(timeout)); return nn_recvmsg (s, &hdr, flags); }
int nn_ws_recv (int s, void *msg, size_t len, uint8_t *msg_type, int flags) { struct nn_iovec iov; struct nn_msghdr hdr; struct nn_cmsghdr *cmsg; void *cmsg_buf; int rc; iov.iov_base = msg; iov.iov_len = len; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = &cmsg_buf; hdr.msg_controllen = NN_MSG; rc = nn_recvmsg (s, &hdr, flags); if (rc < 0) return rc; /* Find WebSocket opcode ancillary property. */ cmsg = NN_CMSG_FIRSTHDR (&hdr); while (cmsg) { if (cmsg->cmsg_level == NN_WS && cmsg->cmsg_type == NN_WS_HDR_OPCODE) { *msg_type = *(uint8_t *) NN_CMSG_DATA (cmsg); break; } cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); } /* WebSocket transport should always report this header. */ nn_assert (cmsg); /* WebSocket transport should always reassemble fragmented messages. */ nn_assert (*msg_type & NN_SWS_FRAME_BITMASK_FIN); /* Return only the message type (opcode). */ if (*msg_type == (NN_WS_MSG_TYPE_GONE | NN_SWS_FRAME_BITMASK_FIN)) *msg_type = NN_WS_MSG_TYPE_GONE; else *msg_type &= NN_SWS_FRAME_BITMASK_OPCODE; nn_freemsg (cmsg_buf); return rc; }
void ftw_socket_inbox_async_recv_worker(void *arg) { /* Opaque pointer into ftw_incoming_request structure using LabVIEW-safe type for PostLVUserEvent. */ int64 opaque; struct ftw_incoming_request *incoming; struct ftw_socket_inbox *self; struct nn_iovec iov; struct nn_msghdr msg; void *msg_ptr; void *hdr_ptr; MgErr lv_err; int socket_err; int rc; /* Notify launching process this thread is constructed. */ ftw_assert(arg); self = (struct ftw_socket_inbox *) arg; nn_sem_post(&self->initialized); lv_err = mgNoErr; socket_err = 0; /* This broker relays messages from the nanomsg socket into the LabVIEW incoming message queue. */ while (!lv_err && !socket_err) { /* Created here, this incoming request should be freed once the response is sent. */ incoming = ftw_malloc(sizeof(struct ftw_incoming_request)); if (incoming == NULL) { lv_err = mFullErr; continue; } iov.iov_base = &msg_ptr; iov.iov_len = NN_MSG; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = &hdr_ptr; msg.msg_controllen = NN_MSG; rc = nn_recvmsg(self->id, &msg, 0); if (rc >= 0) { incoming->inbox = self; incoming->msg_ptr = msg_ptr; incoming->msg_len = nn_chunk_size(msg_ptr); incoming->hdr_ptr = hdr_ptr; incoming->hdr_len = nn_chunk_size(hdr_ptr); opaque = (int64)incoming; lv_err = PostLVUserEvent(self->incoming_msg_notifier_event, &opaque); ftw_assert(lv_err == mgNoErr); /* On the LabVIEW side, the handler is a an Event Handler Structure, which applies no backpressure since the event queue cannot be limited for dynamic events. For this reason, a semaphore is introduced to simulate blocking backpressure, where the semaphore is posted once the Inbox Message Router receives the message. */ nn_sem_wait(&self->msg_acknowledged); } else { /* Treat timeouts as non-fatal. Anything else will stop this thread. */ socket_err = ((errno == ETIMEDOUT || errno == EAGAIN) ? 0 : errno); } } /* Posting a NULL pointer signals the LabVIEW Message Router to shutdown. */ opaque = (int64) NULL; lv_err = PostLVUserEvent(self->incoming_msg_notifier_event, &opaque); ftw_assert(lv_err == mgNoErr); /* Wait for the Message Router to unload. */ nn_sem_wait(&self->deinitialized); return; }
int main() { int back_router = nn_socket(AF_SP_RAW, NN_REP); nn_bind(back_router, BACKROUTER); chan jobs = chmake(char*, 128); chan workers = chmake(char*, 64); go(collect(workers, back_router)); go(generate_work(jobs)); go(route_work(workers, back_router, jobs)); msleep(now() + 5435345); int front_router = nn_socket(AF_SP_RAW, NN_REP); nn_bind(front_router, FRONTROUTER); char ctrl [256]; char body [256]; char ctrl2 [256]; char body2 [256]; struct nn_msghdr hdr; struct nn_msghdr hdr2; struct nn_iovec iovec; iovec.iov_base = body; iovec.iov_len = sizeof(body); memset(&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = ctrl; hdr.msg_controllen = sizeof (ctrl); int rc = nn_recvmsg(back_router, &hdr, 0); printf("got rc: %d, got ctrl: %d\n", rc, hdr.msg_controllen); struct nn_iovec iovec2; iovec2.iov_base = body2; iovec2.iov_len = sizeof(body2); memset(&hdr2, 0, sizeof (hdr)); hdr2.msg_iov = &iovec2; hdr2.msg_iovlen = 1; hdr2.msg_control = ctrl2; hdr2.msg_controllen = sizeof (ctrl2); rc = nn_recvmsg(back_router, &hdr2, 0); /* struct nn_cmsghdr *cmsg; cmsg = NN_CMSG_FIRSTHDR (&hdr); while (cmsg != NULL) { size_t len = cmsg->cmsg_len - sizeof (struct nn_cmsghdr); printf ("level: %d property: %d length: %dB data: ", (int) cmsg->cmsg_level, (int) cmsg->cmsg_type, (int) len); unsigned char *data = NN_CMSG_DATA(cmsg); while (len) { printf ("%02X", *data); ++data; --len; } printf ("\n"); cmsg = NN_CMSG_NXTHDR (&hdr.msg_control, cmsg); } */ hdr.msg_iov = &iovec2; hdr.msg_iovlen = 1; nn_sendmsg(back_router, &hdr, 0); /* while(1){ sleep(10); buf = NULL; printf("waiting for worker\n"); int n = nn_recv(response, &buf, NN_MSG, 0); printf("server got msg: %.*s\n", n, buf); sprintf(tevs, "you are number %d served", ++c); printf("responding to %d\n",response); nn_send(response, tevs, strlen(tevs), 0); nn_freemsg(buf); } nn_shutdown(response, 0); */ return 0; }
int ftw_nanomsg_connector_ask(struct ftw_socket ** const sock, int send_timeout, int recv_timeout, const LStrHandle request, LStrHandle response) { int rc; struct nn_iovec iov; struct nn_msghdr hdr; void *recv_buf; MgErr resize_err; struct ftw_socket const *s; s = *sock; if (s == NULL) { errno = EBADF; return -1; } iov.iov_base = LHStrBuf(request); iov.iov_len = LHStrLen(request); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = NULL; hdr.msg_controllen = 0; rc = nn_setsockopt(s->id, NN_SOL_SOCKET, NN_SNDTIMEO, &send_timeout, sizeof(send_timeout)); if (rc < 0) return rc; rc = nn_setsockopt(s->id, NN_SOL_SOCKET, NN_RCVTIMEO, &recv_timeout, sizeof(recv_timeout)); if (rc < 0) return rc; rc = nn_sendmsg(s->id, &hdr, 0); if (rc >= 0) { recv_buf = NULL; iov.iov_base = &recv_buf; iov.iov_len = NN_MSG; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = NULL; hdr.msg_controllen = 0; rc = nn_recvmsg(s->id, &hdr, 0); if (rc >= 0) { resize_err = ftw_support_buffer_to_LStrHandle(&response, recv_buf, rc); if (resize_err != mgNoErr) { errno = resize_err + LV_USER_ERROR; rc = -1; } } if (recv_buf) nn_freemsg(recv_buf); } return rc; }
int testmsg() { int rc; int sb; int sc; unsigned char *buf1, *buf2; int i; struct nn_iovec iov; struct nn_msghdr hdr; printf("test msg\n"); if ( 1 ) { sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); buf1 = nn_allocmsg (256, 0); alloc_assert (buf1); for (i = 0; i != 256; ++i) buf1 [i] = (unsigned char) i; printf("send 256\n"); rc = nn_send (sc, &buf1, NN_MSG, 0); printf("rc.%d\n",rc); errno_assert (rc >= 0); nn_assert (rc == 256); buf2 = NULL; rc = nn_recv (sb, &buf2, NN_MSG, 0); errno_assert (rc >= 0); nn_assert (rc == 256); nn_assert (buf2); for (i = 0; i != 256; ++i) nn_assert (buf2 [i] == (unsigned char) i); rc = nn_freemsg (buf2); errno_assert (rc == 0); buf1 = nn_allocmsg (256, 0); alloc_assert (buf1); for (i = 0; i != 256; ++i) buf1 [i] = (unsigned char) i; iov.iov_base = &buf1; iov.iov_len = NN_MSG; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; rc = nn_sendmsg (sc, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 256); buf2 = NULL; iov.iov_base = &buf2; iov.iov_len = NN_MSG; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; rc = nn_recvmsg (sb, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 256); nn_assert (buf2); for (i = 0; i != 256; ++i) nn_assert (buf2 [i] == (unsigned char) i); rc = nn_freemsg (buf2); errno_assert (rc == 0); test_close (sc); test_close (sb); } /* Test receiving of large message */ sb = test_socket(AF_SP, NN_PAIR); //printf("test_bind.(%s)\n",SOCKET_ADDRESS_TCP); test_bind(sb,SOCKET_ADDRESS_TCP); sc = test_socket(AF_SP,NN_PAIR); //printf("test_connect.(%s)\n",SOCKET_ADDRESS_TCP); test_connect(sc,SOCKET_ADDRESS_TCP); for (i = 0; i < (int) sizeof (longdata); ++i) longdata[i] = '0' + (i % 10); longdata [sizeof(longdata) - 1] = 0; printf("send longdata.%d\n",(int32_t)sizeof(longdata)); test_send(sb,longdata); printf("recv longdata.%d\n",(int32_t)sizeof(longdata)); rc = nn_recv (sc, &buf2, NN_MSG, 0); errno_assert (rc >= 0); nn_assert (rc == sizeof (longdata) - 1); nn_assert (buf2); for (i = 0; i < (int) sizeof (longdata) - 1; ++i) nn_assert (buf2 [i] == longdata [i]); rc = nn_freemsg (buf2); errno_assert (rc == 0); test_close (sc); test_close (sb); //printf("testmsg completed\n"); return 0; }
int main () { int rc; int rep; int req; struct nn_msghdr hdr; struct nn_iovec iovec; unsigned char body [3]; unsigned char ctrl [256]; struct nn_cmsghdr *cmsg; unsigned char *data; void *buf; rep = test_socket (AF_SP_RAW, NN_REP); test_bind (rep, SOCKET_ADDRESS); req = test_socket (AF_SP, NN_REQ); test_connect (req, SOCKET_ADDRESS); /* Test ancillary data in static buffer. */ test_send (req, "ABC"); iovec.iov_base = body; iovec.iov_len = sizeof (body); hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = ctrl; hdr.msg_controllen = sizeof (ctrl); rc = nn_recvmsg (rep, &hdr, 0); errno_assert (rc == 3); cmsg = NN_CMSG_FIRSTHDR (&hdr); while (1) { nn_assert (cmsg); if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) break; cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); } nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8)); data = NN_CMSG_DATA (cmsg); nn_assert (!(data[0] & 0x80)); nn_assert (data[4] & 0x80); rc = nn_sendmsg (rep, &hdr, 0); nn_assert (rc == 3); test_recv (req, "ABC"); /* Test ancillary data in dynamically allocated buffer (NN_MSG). */ test_send (req, "ABC"); iovec.iov_base = body; iovec.iov_len = sizeof (body); hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = &buf; hdr.msg_controllen = NN_MSG; rc = nn_recvmsg (rep, &hdr, 0); errno_assert (rc == 3); cmsg = NN_CMSG_FIRSTHDR (&hdr); while (1) { nn_assert (cmsg); if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) break; cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); } nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8)); data = NN_CMSG_DATA (cmsg); nn_assert (!(data[0] & 0x80)); nn_assert (data[4] & 0x80); rc = nn_sendmsg (rep, &hdr, 0); nn_assert (rc == 3); test_recv (req, "ABC"); test_close (req); test_close (rep); return 0; }
int main (int argc, const char *argv[]) { int rc; int sb; int sc; unsigned char *buf1, *buf2; int i; struct nn_iovec iov; struct nn_msghdr hdr; char socket_address_tcp[128]; test_addr_from(socket_address_tcp, "tcp", "127.0.0.1", get_test_port(argc, argv)); sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); buf1 = nn_allocmsg (256, 0); alloc_assert (buf1); for (i = 0; i != 256; ++i) buf1 [i] = (unsigned char) i; rc = nn_send (sc, &buf1, NN_MSG, 0); errno_assert (rc >= 0); nn_assert (rc == 256); buf2 = NULL; rc = nn_recv (sb, &buf2, NN_MSG, 0); errno_assert (rc >= 0); nn_assert (rc == 256); nn_assert (buf2); for (i = 0; i != 256; ++i) nn_assert (buf2 [i] == (unsigned char) i); rc = nn_freemsg (buf2); errno_assert (rc == 0); buf1 = nn_allocmsg (256, 0); alloc_assert (buf1); for (i = 0; i != 256; ++i) buf1 [i] = (unsigned char) i; iov.iov_base = &buf1; iov.iov_len = NN_MSG; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; rc = nn_sendmsg (sc, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 256); buf2 = NULL; iov.iov_base = &buf2; iov.iov_len = NN_MSG; memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; rc = nn_recvmsg (sb, &hdr, 0); errno_assert (rc >= 0); nn_assert (rc == 256); nn_assert (buf2); for (i = 0; i != 256; ++i) nn_assert (buf2 [i] == (unsigned char) i); rc = nn_freemsg (buf2); errno_assert (rc == 0); test_close (sc); test_close (sb); /* Test receiving of large message */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, socket_address_tcp); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, socket_address_tcp); for (i = 0; i < (int) sizeof (longdata); ++i) longdata[i] = '0' + (i % 10); longdata [sizeof (longdata) - 1] = 0; test_send (sb, longdata); rc = nn_recv (sc, &buf2, NN_MSG, 0); errno_assert (rc >= 0); nn_assert (rc == sizeof (longdata) - 1); nn_assert (buf2); for (i = 0; i < (int) sizeof (longdata) - 1; ++i) nn_assert (buf2 [i] == longdata [i]); rc = nn_freemsg (buf2); errno_assert (rc == 0); test_close (sc); test_close (sb); return 0; }
int main () { int rc; int sb; int sc; int s1, s2; int i; char buf [256]; int val; struct nn_msghdr hdr; struct nn_iovec iovec; unsigned char body [3]; void *control; struct nn_cmsghdr *cmsg; unsigned char *data; /* Create a simple topology. */ sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); /* Try a duplicate bind. It should fail. */ rc = nn_bind (sc, SOCKET_ADDRESS); nn_assert (rc < 0 && errno == EADDRINUSE); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { test_send (sc, "ABC"); test_recv (sb, "ABC"); test_send (sb, "DEFG"); test_recv (sc, "DEFG"); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { test_send (sc, "XYZ"); } for (i = 0; i != 100; ++i) { test_recv (sb, "XYZ"); } test_close (sc); test_close (sb); /* Test whether queue limits are observed. */ sb = test_socket (AF_SP, NN_PAIR); val = 200; rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVBUF, &val, sizeof (val)); errno_assert (rc == 0); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); val = 200; rc = nn_setsockopt (sc, NN_SOL_SOCKET, NN_SNDTIMEO, &val, sizeof (val)); errno_assert (rc == 0); i = 0; while (1) { rc = nn_send (sc, "0123456789", 10, 0); if (rc < 0 && nn_errno () == EAGAIN) break; errno_assert (rc >= 0); nn_assert (rc == 10); ++i; } nn_assert (i == 20); test_recv (sb, "0123456789"); test_send (sc, "0123456789"); rc = nn_send (sc, "0123456789", 10, 0); nn_assert (rc < 0 && nn_errno () == EAGAIN); for (i = 0; i != 20; ++i) { test_recv (sb, "0123456789"); } /* Make sure that even a message that doesn't fit into the buffers gets across. */ for (i = 0; i != sizeof (buf); ++i) buf [i] = 'A'; rc = nn_send (sc, buf, 256, 0); errno_assert (rc >= 0); nn_assert (rc == 256); rc = nn_recv (sb, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 256); test_close (sc); test_close (sb); #if 0 /* Test whether connection rejection is handled decently. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); s1 = test_socket (AF_SP, NN_PAIR); test_connect (s1, SOCKET_ADDRESS); s2 = test_socket (AF_SP, NN_PAIR); test_connect (s2, SOCKET_ADDRESS); nn_sleep (100); test_close (s2); test_close (s1); test_close (sb); #endif /* Check whether SP message header is transferred correctly. */ sb = test_socket (AF_SP_RAW, NN_REP); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_REQ); test_connect (sc, SOCKET_ADDRESS); test_send (sc, "ABC"); iovec.iov_base = body; iovec.iov_len = sizeof (body); hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = &control; hdr.msg_controllen = NN_MSG; rc = nn_recvmsg (sb, &hdr, 0); errno_assert (rc == 3); cmsg = NN_CMSG_FIRSTHDR (&hdr); while (1) { nn_assert (cmsg); if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) break; cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); } nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8)); data = NN_CMSG_DATA (cmsg); nn_assert (!(data[0] & 0x80)); nn_assert (data[4] & 0x80); nn_freemsg (control); test_close (sc); test_close (sb); /* Test binding a new socket after originally bound socket shuts down. */ sb = test_socket (AF_SP, NN_BUS); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_BUS); test_connect (sc, SOCKET_ADDRESS); s1 = test_socket (AF_SP, NN_BUS); test_connect (s1, SOCKET_ADDRESS); /* Close bound socket, leaving connected sockets connect. */ test_close (sb); nn_sleep (100); /* Rebind a new socket to the address to which our connected sockets are listening. */ s2 = test_socket (AF_SP, NN_BUS); test_bind (s2, SOCKET_ADDRESS); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { test_send (sc, "ABC"); test_send (s1, "QRS"); test_recv (s2, "ABC"); test_recv (s2, "QRS"); test_send (s2, "DEFG"); test_recv (sc, "DEFG"); test_recv (s1, "DEFG"); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { test_send (sc, "XYZ"); } for (i = 0; i != 100; ++i) { test_recv (s2, "XYZ"); } for (i = 0; i != 100; ++i) { test_send (s1, "MNO"); } for (i = 0; i != 100; ++i) { test_recv (s2, "MNO"); } test_close (s1); test_close (sc); test_close (s2); return 0; }