|  | @@ -1,87 +1,95 @@
 | 
	
		
			
				|  |  |  #include <arpa/inet.h>
 | 
	
		
			
				|  |  |  #include <iostream>
 | 
	
		
			
				|  |  |  #include <stdexcept>
 | 
	
		
			
				|  |  | -#include <stdio.h>  //printf
 | 
	
		
			
				|  |  | +#include <netdb.h>  //printf
 | 
	
		
			
				|  |  |  #include <stdlib.h> //exit(0);
 | 
	
		
			
				|  |  |  #include <cstring> //memset
 | 
	
		
			
				|  |  |  #include <sys/socket.h>
 | 
	
		
			
				|  |  |  #include <unistd.h>
 | 
	
		
			
				|  |  | +#include <netinet/in.h>
 | 
	
		
			
				|  |  | +#include <sys/types.h>
 | 
	
		
			
				|  |  |  #include <vector>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define SERVER "127.0.0.1"
 | 
	
		
			
				|  |  |  #define BUFLEN 1024 // Max length of buffer
 | 
	
		
			
				|  |  |  #define PORT 8888   // The port on which to send data
 | 
	
		
			
				|  |  |  class udpsocket {
 | 
	
		
			
				|  |  | -  struct sockaddr_in addr;
 | 
	
		
			
				|  |  | -  int s, slen = sizeof(addr);
 | 
	
		
			
				|  |  | -public:
 | 
	
		
			
				|  |  | -  udpsocket(int port);
 | 
	
		
			
				|  |  | -  udpsocket(const udpsocket&) = delete;
 | 
	
		
			
				|  |  | -  udpsocket& operator=(const udpsocket&) = delete;
 | 
	
		
			
				|  |  | -  udpsocket(udpsocket&&);
 | 
	
		
			
				|  |  | -  udpsocket& operator=(udpsocket&&);
 | 
	
		
			
				|  |  | -  void write(const std::string&,const std::string& dest, int port);
 | 
	
		
			
				|  |  | -  void write(const std::vector<char>&,const std::string& dest, int port);
 | 
	
		
			
				|  |  | -  std::vector<char> receive();
 | 
	
		
			
				|  |  | -  void close();
 | 
	
		
			
				|  |  | +	struct sockaddr_in addr;
 | 
	
		
			
				|  |  | +	int s, slen = sizeof(addr);
 | 
	
		
			
				|  |  | +	public:
 | 
	
		
			
				|  |  | +	udpsocket(int port);
 | 
	
		
			
				|  |  | +	udpsocket(const udpsocket&) = delete;
 | 
	
		
			
				|  |  | +	udpsocket& operator=(const udpsocket&) = delete;
 | 
	
		
			
				|  |  | +	udpsocket(udpsocket&&);
 | 
	
		
			
				|  |  | +	udpsocket& operator=(udpsocket&&);
 | 
	
		
			
				|  |  | +	void write(const std::string&,const std::string& dest, int port);
 | 
	
		
			
				|  |  | +	void write(const std::vector<char>&,const std::string& dest, int port);
 | 
	
		
			
				|  |  | +	std::vector<char> receive();
 | 
	
		
			
				|  |  | +	void close();
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  udpsocket::udpsocket(int port) {
 | 
	
		
			
				|  |  | -  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 | 
	
		
			
				|  |  | -    throw std::logic_error(std::string("Socket creation failed: ") + strerror(errno));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  std::memset((char*)&addr, 0, sizeof(addr));
 | 
	
		
			
				|  |  | -  addr.sin_family = AF_INET;
 | 
	
		
			
				|  |  | -  addr.sin_addr.s_addr = htonl(INADDR_ANY);
 | 
	
		
			
				|  |  | -  addr.sin_port = htons(port);
 | 
	
		
			
				|  |  | +	if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 | 
	
		
			
				|  |  | +		throw std::logic_error(std::string("Socket creation failed: ") + strerror(errno));
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	std::memset((char*)&addr, 0, sizeof(addr));
 | 
	
		
			
				|  |  | +	addr.sin_family = AF_INET;
 | 
	
		
			
				|  |  | +	addr.sin_addr.s_addr = htonl(INADDR_ANY);
 | 
	
		
			
				|  |  | +	addr.sin_port = htons(port);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
 | 
	
		
			
				|  |  | -    throw std::logic_error(std::string("Socket binding failed: ") + strerror(errno));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +	if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
 | 
	
		
			
				|  |  | +		throw std::logic_error(std::string("Socket binding failed: ") + strerror(errno));
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -udpsocket::udpsocket(udpsocket&& o) : addr(o.addr),s(o.s){
 | 
	
		
			
				|  |  | -  o.s = 0;
 | 
	
		
			
				|  |  | +udpsocket::udpsocket(udpsocket&& o) : addr(o.addr),s(o.s) {
 | 
	
		
			
				|  |  | +	o.s = 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  udpsocket& udpsocket::operator=(udpsocket&& o){
 | 
	
		
			
				|  |  | -  addr = o.addr;
 | 
	
		
			
				|  |  | -  s = o.s;
 | 
	
		
			
				|  |  | -  o.s = 0;
 | 
	
		
			
				|  |  | -  return *this;
 | 
	
		
			
				|  |  | +	addr = o.addr;
 | 
	
		
			
				|  |  | +	s = o.s;
 | 
	
		
			
				|  |  | +	o.s = 0;
 | 
	
		
			
				|  |  | +	return *this;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void udpsocket::write(const std::string& msg, const std::string& dest, int port){
 | 
	
		
			
				|  |  | -  std::vector<char> _msg(msg.begin(), msg.end());
 | 
	
		
			
				|  |  | -  write(_msg, dest, port);
 | 
	
		
			
				|  |  | +	std::vector<char> _msg(msg.begin(), msg.end());
 | 
	
		
			
				|  |  | +	write(_msg, dest, port);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void udpsocket::write(const std::vector<char>& msg, const std::string& dest, int port){
 | 
	
		
			
				|  |  | -  struct sockaddr_in _dest;
 | 
	
		
			
				|  |  | -  std::memset((char*)&_dest, 0, sizeof(sockaddr_in));
 | 
	
		
			
				|  |  | -  _dest.sin_family = AF_INET;
 | 
	
		
			
				|  |  | -  _dest.sin_port = htons(PORT);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (inet_aton(dest.c_str(), &_dest.sin_addr) == 0) {
 | 
	
		
			
				|  |  | -    throw std::logic_error(std::string("inet_aton() failed: ") + strerror(errno));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  if (sendto(s, msg.data(), msg.size(), 0, (struct sockaddr*)&dest, slen) < 0) {
 | 
	
		
			
				|  |  | -    throw std::logic_error(std::string("Could not send packet: ") + strerror(errno));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +	hostent *server_host;
 | 
	
		
			
				|  |  | +	errno = 0;
 | 
	
		
			
				|  |  | +	server_host = gethostbyname(dest.c_str());
 | 
	
		
			
				|  |  | +	if(errno){
 | 
	
		
			
				|  |  | +		throw std::logic_error("Could not resolve hostname " + dest + ": " + strerror(errno));
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	/* configure the server address */
 | 
	
		
			
				|  |  | +	struct sockaddr_in server_addr;
 | 
	
		
			
				|  |  | +	server_addr.sin_family = AF_INET; // IPv4
 | 
	
		
			
				|  |  | +	memcpy(&server_addr.sin_addr, server_host->h_addr,
 | 
	
		
			
				|  |  | +			sizeof(struct in_addr)); server_addr.sin_port = htons(port);
 | 
	
		
			
				|  |  | +	/* send a message */
 | 
	
		
			
				|  |  | +	if(sendto(s, msg.data(), msg.size(), 0,(const sockaddr*)&server_addr, sizeof(server_addr)) < 0){
 | 
	
		
			
				|  |  | +		throw std::logic_error(std::string("Could not send packet: ") + strerror(errno));
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  std::vector<char> udpsocket::receive(){
 | 
	
		
			
				|  |  | -  std::vector<char> ret(1024);
 | 
	
		
			
				|  |  | -  if (read(s, ret.data(), 1024) <= 0) {
 | 
	
		
			
				|  |  | -    throw std::logic_error(std::string("Could not receive packet: ") + strerror(errno));
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  return ret;
 | 
	
		
			
				|  |  | +	std::vector<char> ret(1024);
 | 
	
		
			
				|  |  | +	if (read(s, ret.data(), 1024) <= 0) {
 | 
	
		
			
				|  |  | +		throw std::logic_error(std::string("Could not receive packet: ") + strerror(errno));
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void udpsocket::close(){
 | 
	
		
			
				|  |  | -  shutdown(s, 2);
 | 
	
		
			
				|  |  | +	shutdown(s, 2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void die(const std::string& s) {
 | 
	
		
			
				|  |  | -  perror(s.c_str());
 | 
	
		
			
				|  |  | -  exit(1);
 | 
	
		
			
				|  |  | +	perror(s.c_str());
 | 
	
		
			
				|  |  | +	exit(1);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  int main() {
 | 
	
		
			
				|  |  | -  udpsocket sock(5566);
 | 
	
		
			
				|  |  | -  sock.write("Hallo", "127.0.0.1",5555);
 | 
	
		
			
				|  |  | -  std::cin.get();
 | 
	
		
			
				|  |  | -  return 0;
 | 
	
		
			
				|  |  | +	udpsocket sock(5566);
 | 
	
		
			
				|  |  | +	std::vector<char> d(23,'a');
 | 
	
		
			
				|  |  | +	while(true)
 | 
	
		
			
				|  |  | +	sock.write(d.data(), "127.0.0.1" ,5555);
 | 
	
		
			
				|  |  | +	std::cin.get();
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  |  }
 |