| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- #include <netdb.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include "Practical.h"
- static const int MAX_PENDING = 5;
- int setup_tcp_server_socket(const char *service) {
- struct addrinfo addr_criteria = { 0 };
- addr_criteria.ai_family = AF_UNSPEC;
- addr_criteria.ai_flags = AI_PASSIVE;
- addr_criteria.ai_socktype = SOCK_STREAM;
- addr_criteria.ai_protocol = proto_get_num("tcp");
- struct addrinfo *serv_addr = nullptr;
- int ret = getaddrinfo(nullptr, service, &addr_criteria, &serv_addr);
- if (ret != 0) {
- DieWithUserMessage("getaddrinfo() failed", gai_strerror(ret));
- }
- int serv_sock = -1;
- for (struct addrinfo *addr = serv_addr; addr != nullptr; addr = addr->ai_next) {
- serv_sock = socket(AF_to_PF(addr->ai_family), addr->ai_socktype, addr->ai_protocol);
- if (serv_sock < 0) {
- continue;
- }
- if (
- (bind(serv_sock, addr->ai_addr, addr->ai_addrlen) == 0)
- && (listen(serv_sock, MAX_PENDING) == 0)
- ) {
- struct sockaddr_storage local_addr;
- socklen_t addr_size = sizeof(local_addr);
- if (getsockname(serv_sock, (struct sockaddr *) &local_addr, &addr_size) < 0) {
- DieWithSystemMessage("getsockname() failed");
- }
- fputs("Binding to: ", stdout);
- PrintSocketAddress((struct sockaddr *) &local_addr, stdout);
- fputc('\n', stdout);
- break;
- } else {
- close(serv_sock);
- serv_sock = -1;
- }
- }
- freeaddrinfo(serv_addr);
- return serv_sock;
- }
- int accept_tcp_connection(const int serv_sock) {
- struct sockaddr_storage client_addr;
- socklen_t client_addr_len = sizeof(client_addr);
- int client_sock = accept(serv_sock, (struct sockaddr *) &client_addr, &client_addr_len);
- if (client_sock < 0) {
- DieWithSystemMessage("accept() failed");
- }
- fputs("Handling client ", stdout);
- PrintSocketAddress((struct sockaddr *) &client_addr, stdout);
- fputc('\n', stdout);
- return client_sock;
- }
- void HandleTCPClient(const int client_sock) {
- char buffer[BUFSIZE];
- ssize_t num_bytes_rcvd = recv(client_sock, buffer, BUFSIZE, 0);
- if (num_bytes_rcvd < 0) {
- DieWithSystemMessage("recv() failed");
- }
- while (num_bytes_rcvd > 0) {
- ssize_t num_bytes_sent = send(client_sock, buffer, num_bytes_rcvd, 0);
- if (num_bytes_sent < 0) {
- DieWithSystemMessage("send() failed");
- } else if (num_bytes_sent != num_bytes_rcvd) {
- DieWithUserMessage("send()", "sent unexpected number of bytes");
- }
- num_bytes_rcvd = recv(client_sock, buffer, BUFSIZE, 0);
- if (num_bytes_rcvd < 0) {
- DieWithSystemMessage("recv() failed");
- }
- }
- close(client_sock);
- }
|