/* create a client connection to a specified host according to a specified host name or an ip address. Inputs: <host> the name of the host <port> the listening port <ip> the ip value of the host, if host is a NULL value Outputs: <ip> the ip value of the host Returns: -1 on failure, otherwise the socket */ int tcp_make_client (char *host, int *port, unsigned int *ip, int nonblocking) { struct sockaddr_in sin; unsigned short listen_port; int fd, st; char localhost[64]; /* set everything up */ listen_port = (unsigned short) *port; memset (&sin, 0, sizeof (sin)); sin.sin_port = htons (listen_port); sin.sin_family = AF_INET; if (!host && !ip) { if (gethostname(localhost,64)==0) host = localhost; else return -1; } if (host) *ip = lookup_ip (host); if (*ip == 0) return -2; sin.sin_addr.s_addr = *ip; /* create a socket */ fd = tcp_open_socket (nonblocking); if (fd < 0) return -3; /* make the connection */ st = connect (fd, (struct sockaddr *) &sin, sizeof (sin)); /* get the local port bound to this socket */ *port = tcp_get_local_port(fd); if (st < 0) { /* for nonblocking, it is okay for the following error # */ if (nonblocking && (NET_ERRNO == EINPROGRESS || NET_ERRNO == EWOULDBLOCK)) { dbgprintf ("connecting to (%s:%hu) at port %hu", inet_ntoa (sin.sin_addr), listen_port, *port); return fd; } dbgprintf ("tcp_make_client : fail to connect to %s error %d", host, NET_ERRNO); closesocket (fd); return -4; } else { dbgprintf ("connected to (%s:%hu) at port %hu", inet_ntoa (sin.sin_addr), listen_port, *port); } return fd; }
/* create a client connection to a specified host Inputs: <iface> the network interface that the server binds <port> the listening port Returns: -1 on failure, otherwise the socket */ int tcp_startup_server(unsigned int iface, int port) { int sockfd; /* create a socket */ sockfd = tcp_open_socket (1); if (sockfd < 0) return -1; /* bind the socket on to a specified interface */ if (bind_interface (sockfd, iface, port) == -1) return -2; if (listen (sockfd, 5) < 0) return -3; dbgprintf ("startup a TCP server %s at port %d fd %d",iptoa (iface),port, sockfd); return sockfd; }
int zmq::tcp_listener_t::create_socket (const char *addr_) { _s = tcp_open_socket (addr_, options, true, true, &_address); if (_s == retired_fd) { return -1; } // TODO why is this only done for the listener? make_socket_noninheritable (_s); // Allow reusing of the address. int flag = 1; int rc; #ifdef ZMQ_HAVE_WINDOWS // TODO this was changed for Windows from SO_REUSEADDRE to // SE_EXCLUSIVEADDRUSE by 0ab65324195ad70205514d465b03d851a6de051c, // so the comment above is no longer correct; also, now the settings are // different between listener and connecter with a src address. // is this intentional? rc = setsockopt (_s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, reinterpret_cast<const char *> (&flag), sizeof (int)); wsa_assert (rc != SOCKET_ERROR); #elif defined ZMQ_HAVE_VXWORKS rc = setsockopt (_s, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof (int)); errno_assert (rc == 0); #else rc = setsockopt (_s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); errno_assert (rc == 0); #endif // Bind the socket to the network interface and port. #if defined ZMQ_HAVE_VXWORKS rc = bind (_s, (sockaddr *) _address.addr (), _address.addrlen ()); #else rc = bind (_s, _address.addr (), _address.addrlen ()); #endif #ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR) { errno = wsa_error_to_errno (WSAGetLastError ()); goto error; } #else if (rc != 0) goto error; #endif // Listen for incoming connections. rc = listen (_s, options.backlog); #ifdef ZMQ_HAVE_WINDOWS if (rc == SOCKET_ERROR) { errno = wsa_error_to_errno (WSAGetLastError ()); goto error; } #else if (rc != 0) goto error; #endif return 0; error: int err = errno; close (); errno = err; return -1; }