protohack-4.cpp (1234B)
1 #include <poll.h> 2 3 #include <iostream> 4 #include <sstream> 5 #include <map> 6 #include <vector> 7 8 #include "inet.hpp" 9 10 using namespace std; 11 12 std::map<string, string> database = {{"version", "m3henry-protohack-4"}}; 13 14 string recv_udp(descriptor& d, sockaddr_in& a) 15 { 16 char buf[1024]; 17 socklen_t addr_size = sizeof a; 18 19 ssize_t n = ::recvfrom(d, buf, sizeof buf, 0, (sockaddr*)&a, &addr_size); 20 if (n > 0) 21 return {buf, (size_t)n}; 22 else 23 return {}; 24 } 25 26 int send_udp(descriptor& d, sockaddr_in const& a, string const& s) 27 { 28 return ::sendto(d, s.data(), s.size(), 0, (sockaddr const*)&a, sizeof a); 29 } 30 31 int main() 32 { 33 auto incoming = inet::listen(SOCK_DGRAM); 34 35 for (;;) 36 { 37 struct sockaddr_in addr; 38 socklen_t addr_size = sizeof addr; 39 char buf[1024]; 40 41 auto len = ::recvfrom(incoming, buf, sizeof buf, 0, (sockaddr*)&addr, &addr_size); 42 if (len < 0) 43 return 1; 44 string msg{buf, (size_t)len}; 45 string ip = inet_ntoa(addr.sin_addr); 46 cout << ip << ":" << addr.sin_port << " '" << msg << "'\n"; 47 48 auto split = msg.find('='); 49 if (split == string::npos) 50 { 51 send_udp(incoming, addr, msg + '=' + database[msg]); 52 continue; 53 } 54 auto key = msg.substr(0, split); 55 if (key != "version") 56 database[key] = msg.substr(split+1); 57 } 58 }