LiVES  3.2.0
htmsocket.c
Go to the documentation of this file.
1 // htmsocket.c
2 // LiVES
3 // (c) G. Finch 2008 - 2015 <salsaman@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING for licensing details
6 
7 #include "main.h"
8 
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <errno.h>
12 
13 #ifndef IS_MINGW
14 #include <netinet/in.h>
15 #include <netdb.h>
16 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #else
19 #include <ws2tcpip.h>
20 #endif
21 
22 #if IS_SOLARIS
23 #include <sys/filio.h>
24 #endif
25 
26 #include "htmsocket.h"
27 
28 typedef struct {
29  struct sockaddr_in serv_addr;
30  int sockfd;
31  int len;
32 #ifdef __cplusplus
33  sockaddr *addr;
34 #else
35  void *addr;
36 #endif
37 } desc;
38 
39 
40 void *OpenHTMSocket(const char *host, int portnumber, boolean sender) {
41  int sockfd;
42  struct sockaddr_in cl_addr;
43  desc *o;
44  struct hostent *hostsEntry;
45  uint64_t address = 0;
46 
47  o = (desc *)malloc(sizeof(desc));
48  if (o == NULL) return NULL;
49 
50  o->len = sizeof(cl_addr);
51  lives_memset((char *)&o->serv_addr, 0, sizeof(o->serv_addr));
52  o->serv_addr.sin_family = AF_INET;
53 
54  if (strcmp(host, "INADDR_ANY")) {
55  hostsEntry = gethostbyname(host);
56 
57  if (hostsEntry == NULL) {
58  lives_free(o);
59  return NULL;
60  }
61 
62  address = *((uint64_t *) hostsEntry->h_addr_list[0]);
63  }
64 
65  if (sender) {
66  // open sender socket
67  o->serv_addr.sin_addr.s_addr = address;
68  o->serv_addr.sin_port = htons(portnumber);
69  } else {
70  // open receiver socket
71  if (!strcmp(host, "INADDR_ANY")) o->serv_addr.sin_addr.s_addr = INADDR_ANY;
72  else o->serv_addr.sin_addr.s_addr = address;
73  o->serv_addr.sin_port = htons(0);
74  }
75 
76 #ifdef __cplusplus
77  o->addr = (sockaddr *) & (o->serv_addr);
78 #else
79  o->addr = &(o->serv_addr);
80 #endif
81 
82  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
83  lives_memset((char *)&cl_addr, 0, sizeof(cl_addr));
84  cl_addr.sin_family = AF_INET;
85  if (sender) {
86  // bind on all interfaces, any port
87  cl_addr.sin_addr.s_addr = INADDR_ANY;
88  cl_addr.sin_port = htons(0);
89  } else {
90  // bind on all interfaces, specified port
91  cl_addr.sin_addr.s_addr = INADDR_ANY;
92  cl_addr.sin_port = htons(portnumber);
93  }
94  if (bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) {
95  lives_printerr("could not bind\n");
96  close(sockfd);
97  sockfd = -1;
98  }
99  } else lives_printerr("unable to make socket\n");
100 
101  if (sockfd < 0) {
102  lives_free(o);
103  o = NULL;
104  } else {
105  int mxsize = 1024 * 1024;
106  o->sockfd = sockfd;
107  if (!sender) setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *) &mxsize, sizeof(mxsize));
108  }
109 
110  if (o != NULL && strcmp(host, "INADDR_ANY")) {
111  connect(sockfd, o->addr, sizeof(cl_addr));
112  }
113 
114  return o;
115 }
116 
117 
118 static ssize_t getudp(struct sockaddr *sp, int sockfd, int length, size_t count, void *b, int bfsize) {
119  int flags = 0;
120  ssize_t res;
121  unsigned long len;
122 
123  if (bfsize > 0) {
124  int xbfsize;
125  socklen_t slt = sizeof(xbfsize);
126  setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *) &bfsize, sizeof(bfsize));
127  getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *) &xbfsize, &slt);
128  if (xbfsize < bfsize) return -2;
129  }
130 
131 #ifdef IS_MINGW
132  ioctlsocket(sockfd, FIONREAD, &len);
133 #else
134  ioctl(sockfd, FIONREAD, &len);
135 #endif
136 
137  if (len == 0) return -1;
138 
139  do {
140  res = recvfrom(sockfd, b, count, flags, sp, (socklen_t *)&length);
141  //g_print("res is %d\n",res);
142  } while (res == -1);
143 
144  return res;
145 }
146 
147 
148 static boolean sendudp(const struct sockaddr *sp, int sockfd, int length, size_t count, void *b) {
149  size_t rcount;
150  if ((rcount = sendto(sockfd, b, count, 0, sp, length)) != count) {
151  //printf("sockfd %d count %d rcount %dlength %d errno %d\n", sockfd,count,rcount,length,errno);
152  return FALSE;
153  }
154  return TRUE;
155 }
156 
157 
158 boolean lives_stream_out(void *htmsendhandle, size_t length, void *buffer) {
159  desc *o = (desc *)(htmsendhandle);
160  return sendudp(o->addr, o->sockfd, o->len, length, buffer);
161 }
162 
163 ssize_t lives_stream_in(void *htmrecvhandle, size_t length, void *buffer, int bfsize) {
164  desc *o = (desc *)htmrecvhandle;
165 #ifdef __cplusplus
166  return getudp((sockaddr *)o->addr, o->sockfd, o->len, length, buffer, bfsize);
167 #else
168  return getudp(o->addr, o->sockfd, o->len, length, buffer, bfsize);
169 #endif
170 }
171 
172 
173 void CloseHTMSocket(void *htmsendhandle) {
174  desc *o = (desc *)htmsendhandle;
175  close(o->sockfd);
176  lives_free(o);
177 }
178 
lives_free
#define lives_free
Definition: machinestate.h:52
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_memset
#define lives_memset
Definition: machinestate.h:61
lives_stream_out
boolean lives_stream_out(void *htmsendhandle, size_t length, void *buffer)
Definition: htmsocket.c:158
OpenHTMSocket
void * OpenHTMSocket(const char *host, int portnumber, boolean sender)
Definition: htmsocket.c:40
lives_stream_in
ssize_t lives_stream_in(void *htmrecvhandle, size_t length, void *buffer, int bfsize)
Definition: htmsocket.c:163
CloseHTMSocket
void CloseHTMSocket(void *htmsendhandle)
Definition: htmsocket.c:173
main.h
FALSE
#define FALSE
Definition: videoplugin.h:60
htmsocket.h