AiCPlayer
Interface of aic vm - for rendering aspect, sensors, video records
socket.c
Go to the documentation of this file.
1 
5 #include <errno.h> // for errno
6 #include <netinet/in.h> // for IPPROTO_TCP
7 #include <netdb.h> // for addrinfo
8 #include <netinet/tcp.h> // for TCP_NODELAY
9 #include <stdio.h> // for NULL
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <sys/socket.h> // for AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
14 
15 #include "socket.h"
16 #include "logger.h"
17 
18 #define LOG_TAG "socket"
19 
20 typedef enum open_type
21 {
25 } open_type_t;
26 
27 static socket_t open_socket_switch(const char* ip, short port, open_type_t type);
28 
29 socket_t open_socket(const char* ip, short port)
30 {
31  return open_socket_switch(ip, port, NONE);
32 }
33 
34 socket_t open_socket_nodelay(const char* ip, short port)
35 {
36  return open_socket_switch(ip, port, NODELAY);
37 }
38 
39 socket_t open_socket_reuseaddr(const char* ip, short port)
40 {
41  return open_socket_switch(ip, port, REUSEADDR);
42 }
43 
44 static socket_t open_socket_switch(const char* ip, short port, open_type_t type)
45 {
46  socket_t sockfd;
47  struct addrinfo hints, *servinfo, *p;
48  int rv;
49  int yes = 1;
50  char sport[6];
51 
52  snprintf(sport, 6, "%d", port);
53 
54  memset(&hints, 0, sizeof hints);
55  hints.ai_family = AF_INET;
56  hints.ai_socktype = SOCK_STREAM;
57 
58  if ((rv = getaddrinfo(ip, sport, &hints, &servinfo)) != 0)
59  {
60  LOGW("Error in getaddrinfo: %s\n", gai_strerror(rv));
61  return SOCKET_ERROR;
62  }
63 
64  // loop through all the results and connect to the first we can
65  for (p = servinfo; p != NULL; p = p->ai_next)
66  {
67  if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
68  {
69  LOGW("Socket connect error: %s", strerror(errno));
70  continue;
71  }
72 
73  if (type == NODELAY)
74  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(int)); // 2
75  else if (REUSEADDR)
76  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); // 3
77 
78  if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
79  {
80  LOGW("Socket connect error: %s", strerror(errno));
81  close(sockfd);
82  continue;
83  }
84 
85  break; // if we get here, we must have connected successfully
86  }
87 
88  if (p == NULL)
89  {
90  // looped off the end of the list with no connection
91  LOGW("Failed to connect to %s:%d", ip, port);
92  return SOCKET_ERROR;
93  }
94 
95  freeaddrinfo(servinfo); // all done with this structure
96 
97  return sockfd;
98 }
socket_t open_socket(const char *ip, short port)
Connect to a host:port couple.
Definition: socket.c:29
open_type
Definition: socket.c:20
enum open_type open_type_t
Definition: socket.c:22
int socket_t
Alias to differenciate between regular ints and socket fds.
Definition: socket.h:13
socket_t open_socket_nodelay(const char *ip, short port)
Open a socket with TCP_NODELAY.
Definition: socket.c:34
Definition: socket.c:24
socket_t open_socket_reuseaddr(const char *ip, short port)
Open a socket with SO_REUSEADDR.
Definition: socket.c:39
Logging macros.
#define LOGW(...)
Log at WARNING level.
Definition: logger.h:27
#define SOCKET_ERROR
Alias for the recv() return value in case of error.
Definition: socket.h:10
Define socket utilities to simplify networking.