public Ipv4Address resolve(string host) { Debug.Assert(dispatcher != null); if (dispatcher.interrupted()) { throw InterruptedException(); } addrinfo hints = new addrinfo(0, AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, null, null, null); addrinfo addressInfos; int result = getaddrinfo(host, null, hints, addressInfos); if (result != 0) { throw new System.Exception("Ipv4Resolver::resolve, getaddrinfo failed, " + errorMessage(result)); } uint count = 0; for (addrinfo *addressInfo = addressInfos; addressInfo != null; addressInfo = addressInfo.ai_next) { ++count; } std::mt19937 generator = new std::mt19937(std::random_device()()); uint index = std::uniform_int_distribution <uint>(0, count - 1)(generator); addrinfo addressInfo = addressInfos; for (uint i = 0; i < index; ++i) { addressInfo = addressInfo.ai_next; } //C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#: Ipv4Address address = new Ipv4Address(ntohl(reinterpret_cast <sockaddr_in>(addressInfo.ai_addr).sin_addr.s_addr)); freeaddrinfo(addressInfo); return(address); }
public TcpConnection connect(Ipv4Address address, uint16_t port) { Debug.Assert(dispatcher != null); Debug.Assert(context == null); if (dispatcher.interrupted()) { throw InterruptedException(); } string message; int connection = global::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connection == -1) { message = "socket failed, " + lastErrorMessage(); } else { sockaddr_in bindAddress = new sockaddr_in(); bindAddress.sin_family = AF_INET; bindAddress.sin_port = 0; bindAddress.sin_addr.s_addr = INADDR_ANY; //C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#: if (bind(connection, reinterpret_cast <sockaddr>(bindAddress), sizeof(sockaddr_in)) != 0) { message = "bind failed, " + lastErrorMessage(); } else { int flags = fcntl(connection, F_GETFL, 0); if (flags == -1 || fcntl(connection, F_SETFL, flags | O_NONBLOCK) == -1) { message = "fcntl failed, " + lastErrorMessage(); } else { sockaddr_in addressData = new sockaddr_in(); addressData.sin_family = AF_INET; addressData.sin_port = htons(port); addressData.sin_addr.s_addr = htonl(address.getValue()); //C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#: int result = global::connect(connection, reinterpret_cast <sockaddr>(addressData), sizeof(sockaddr_in)); if (result == -1) { if (errno == EINPROGRESS) { ContextPair contextPair = new ContextPair(); TcpConnectorContextExt connectorContext = new TcpConnectorContextExt(); connectorContext.interrupted = false; connectorContext.context = dispatcher.getCurrentContext(); connectorContext.connection = connection; contextPair.readContext = null; contextPair.writeContext = connectorContext; epoll_event connectEvent = new epoll_event(); connectEvent.events = EPOLLOUT | EPOLLRDHUP | EPOLLERR | EPOLLONESHOT; connectEvent.data.ptr = contextPair; if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, connection, connectEvent) == -1) { message = "epoll_ctl failed, " + lastErrorMessage(); } else { context = connectorContext; dispatcher.getCurrentContext().interruptProcedure = () => { TcpConnectorContextExt connectorContext1 = (TcpConnectorContextExt)context; if (!connectorContext1.interrupted) { if (close(connectorContext1.connection) == -1) { throw new System.Exception("TcpListener::stop, close failed, " + lastErrorMessage()); } connectorContext1.interrupted = true; dispatcher.pushContext(connectorContext1.context); } }; dispatcher.dispatch(); dispatcher.getCurrentContext().interruptProcedure = null; Debug.Assert(dispatcher != null); Debug.Assert(connectorContext.context == dispatcher.getCurrentContext()); Debug.Assert(contextPair.readContext == null); Debug.Assert(context == connectorContext); context = null; connectorContext.context = null; if (connectorContext.interrupted) { throw InterruptedException(); } if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_DEL, connection, null) == -1) { message = "epoll_ctl failed, " + lastErrorMessage(); } else { if ((connectorContext.events & (EPOLLERR | EPOLLHUP)) != 0) { int result = close(connection); if (result != 0) { } Debug.Assert(result != -1); throw new System.Exception("TcpConnector::connect, connection failed"); } int retval = -1; socklen_t retValLen = sizeof(int); int s = getsockopt(connection, SOL_SOCKET, SO_ERROR, retval, retValLen); if (s == -1) { message = "getsockopt failed, " + lastErrorMessage(); } else { if (retval != 0) { message = "getsockopt failed, " + lastErrorMessage(); } else { return(new TcpConnection(dispatcher, connection)); } } } } } } else { return(new TcpConnection(dispatcher, connection)); } } } int result = close(connection); if (result != 0) { } Debug.Assert(result != -1); } throw new System.Exception("TcpConnector::connect, " + message); }
public TcpListener(Dispatcher dispatcher, Ipv4Address addr, uint16_t port) { this.dispatcher = dispatcher; string message; listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listener == -1) { message = "socket failed, " + lastErrorMessage(); } else { int flags = fcntl(listener, F_GETFL, 0); if (flags == -1 || fcntl(listener, F_SETFL, flags | O_NONBLOCK) == -1) { message = "fcntl failed, " + lastErrorMessage(); } else { int on = 1; if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, on, sizeof(int)) == -1) { message = "setsockopt failed, " + lastErrorMessage(); } else { sockaddr_in address = new sockaddr_in(); address.sin_family = AF_INET; address.sin_port = htons(port); address.sin_addr.s_addr = htonl(addr.getValue()); //C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#: if (bind(listener, reinterpret_cast <sockaddr>(address), sizeof(sockaddr_in)) != 0) { message = "bind failed, " + lastErrorMessage(); } else if (listen(listener, SOMAXCONN) != 0) { message = "listen failed, " + lastErrorMessage(); } else { epoll_event listenEvent = new epoll_event(); listenEvent.events = EPOLLONESHOT; listenEvent.data.ptr = null; if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, listener, listenEvent) == -1) { message = "epoll_ctl failed, " + lastErrorMessage(); } else { context = null; return; } } } } int result = close(listener); if (result != 0) { } Debug.Assert(result != -1); } throw new System.Exception("TcpListener::TcpListener, " + message); }