|
3 | 3 | #include <iostream>
|
4 | 4 | #include <netdb.h>
|
5 | 5 | #include <string>
|
6 |
| -#include <system_error> |
7 | 6 | #include <unistd.h>
|
8 | 7 | #include <arpa/inet.h>
|
9 | 8 | #include <sys/socket.h>
|
10 | 9 | #include <sys/types.h>
|
11 | 10 |
|
12 | 11 | int main(int argc, char* argv[]) {
|
13 |
| - // Flush after every std::cout / std::cerr |
| 12 | + // Disable output buffering |
14 | 13 | std::cout << std::unitbuf;
|
15 | 14 | std::cerr << std::unitbuf;
|
16 | 15 |
|
17 |
| - // You can use print statements as follows for debugging, they'll be visible when running tests. |
18 |
| - std::cerr << "Logs from your program will appear here!\n"; |
19 |
| - |
20 |
| - // Create socket |
21 | 16 | int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
22 | 17 | if (server_fd < 0) {
|
23 |
| - throw std::system_error(errno, std::generic_category(), "Failed to create server socket"); |
| 18 | + std::cerr << "Failed to create server socket: " << std::endl; |
| 19 | + return 1; |
24 | 20 | }
|
25 | 21 |
|
26 |
| - // Set socket options |
| 22 | + // Since the tester restarts your program quite often, setting SO_REUSEADDR |
| 23 | + // ensures that we don't run into 'Address already in use' errors |
27 | 24 | int reuse = 1;
|
28 | 25 | if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
|
29 | 26 | close(server_fd);
|
30 |
| - throw std::system_error(errno, std::generic_category(), "setsockopt failed"); |
| 27 | + std::cerr << "setsockopt failed: " << std::endl; |
| 28 | + return 1; |
31 | 29 | }
|
32 | 30 |
|
33 |
| - // Configure server address |
34 | 31 | struct sockaddr_in server_addr{};
|
35 | 32 | server_addr.sin_family = AF_INET;
|
36 | 33 | server_addr.sin_addr.s_addr = INADDR_ANY;
|
37 | 34 | server_addr.sin_port = htons(9092);
|
38 | 35 |
|
39 |
| - // Bind socket |
40 | 36 | if (bind(server_fd, reinterpret_cast<struct sockaddr*>(&server_addr), sizeof(server_addr)) != 0) {
|
41 | 37 | close(server_fd);
|
42 |
| - throw std::system_error(errno, std::generic_category(), "Failed to bind to port 9092"); |
| 38 | + std::cerr << "Failed to bind to port 9092" << std::endl; |
| 39 | + return 1; |
43 | 40 | }
|
44 | 41 |
|
45 |
| - // Listen for connections |
46 | 42 | int connection_backlog = 5;
|
47 | 43 | if (listen(server_fd, connection_backlog) != 0) {
|
48 | 44 | close(server_fd);
|
49 |
| - throw std::system_error(errno, std::generic_category(), "listen failed"); |
| 45 | + std::cerr << "listen failed" << std::endl; |
| 46 | + return 1; |
50 | 47 | }
|
51 | 48 |
|
52 | 49 | std::cout << "Waiting for a client to connect...\n";
|
53 | 50 |
|
54 |
| - // Accept client connection |
55 | 51 | struct sockaddr_in client_addr{};
|
56 | 52 | socklen_t client_addr_len = sizeof(client_addr);
|
| 53 | + |
| 54 | + // You can use print statements as follows for debugging, they'll be visible when running tests. |
| 55 | + std::cerr << "Logs from your program will appear here!\n"; |
57 | 56 |
|
58 | 57 | // Uncomment this block to pass the first stage
|
59 | 58 | //
|
|
0 commit comments