ClientSocket::ClientSocket(const char *host, int port)
{
	// construct network address for server
	struct addrinfo hint;
	std::memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_INET;
	hint.ai_socktype = SOCK_STREAM;

	struct addrinfo* infolist{ nullptr };
	int gai_error = ::getaddrinfo(host, std::to_string(port).c_str(), &hint, &infolist);

	if (gai_error)
	{
		std::ostringstream oss;
		oss << "getaddrinfo error " << gai_error << ": " << gai_strerror(gai_error) << " (" << __FILE__ << ":" << __LINE__ << ")";
		throw ConnectionException(oss.str());
	}

	// wrap our list pointer inside unique_ptr for auto cleanup
#if defined(__APPLE__) || defined(__linux__)
	using cleanup_func = void(*)(struct addrinfo*);
	std::unique_ptr<struct addrinfo, cleanup_func> list{ infolist, ::freeaddrinfo };
#else // Windows
	using cleanup_func = void(__stdcall*)(PADDRINFOA);
	std::unique_ptr<struct addrinfo, cleanup_func> list(infolist, ::freeaddrinfo);
#endif

	// create socket
	throw_if_min1(sock = ::socket(list->ai_family, list->ai_socktype, list->ai_protocol));

	// connect to server
	throw_if_min1(::connect(sock, (struct sockaddr*)list->ai_addr, list->ai_addrlen));
}
Beispiel #2
0
ServerSocket::ServerSocket(int port)
{
	throw_if_min1(sock = ::socket(AF_INET, SOCK_STREAM, 0));

	struct sockaddr_in saServer;
	saServer.sin_family = AF_INET;
	saServer.sin_addr.s_addr = INADDR_ANY; 
	saServer.sin_port = htons(port);

	throw_if_min1(::bind(sock, (struct sockaddr*)&saServer, sizeof(struct sockaddr)));
	throw_if_min1(::listen(sock, 100));  // the number of clients that can be queued
}
Beispiel #3
0
void Socket::close()
{
	std::cerr << "will close socket " << sock << std::endl;
#if defined(__APPLE__) || defined(__linux__)
	throw_if_min1(::close(sock));
#else
	::closesocket(sock);
#endif
	sock = 0;
}
Beispiel #4
0
ssize_t Socket::read(char *buf, size_t maxlen)
{
	ssize_t len = 0;
	// might come in parts
	while (ssize_t n = ::recv(sock, buf + len, int(maxlen - len), 0)) {
		throw_if_min1((int)n);
		len += n;
		if (len >= maxlen) break;
	}
	return len;
}
Beispiel #5
0
Socket *ServerSocket::accept()
{
	struct sockaddr client_addr;
	client_addr.sa_family = AF_INET;
	socklen_t len = sizeof(client_addr);
	int fd;
	throw_if_min1(fd = ::accept(sock, &client_addr, &len));
	Socket* client = new Socket(fd, client_addr);
    std::cerr << "Connection accepted from " << client->get_dotted_ip() << ", with socket " << fd << std::endl;
	return client;
}
Beispiel #6
0
std::string Socket::readline()
{
	// read a line: ignore '\r', stop at '\n'
	std::string line;
	char c;
	while (ssize_t n = ::recv(sock, &c, 1, 0)) {
		throw_if_min1((int)n);
		if (c == '\n') break;
		if (c != '\r') line += c;
	}
	return line;
}
Beispiel #7
0
void Socket::write(const char *buf, size_t len)
{
	throw_if_min1((int)::send(sock, buf, (int)len, 0));
}