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
28typedef 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
40void *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
118static 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
148static 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
158boolean 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
163ssize_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
173void CloseHTMSocket(void *htmsendhandle) {
174 desc *o = (desc *)htmsendhandle;
175 close(o->sockfd);
176 lives_free(o);
177}
178
void * OpenHTMSocket(const char *host, int portnumber, boolean sender)
Definition: htmsocket.c:40
boolean lives_stream_out(void *htmsendhandle, size_t length, void *buffer)
Definition: htmsocket.c:158
ssize_t lives_stream_in(void *htmrecvhandle, size_t length, void *buffer, int bfsize)
Definition: htmsocket.c:163
void CloseHTMSocket(void *htmsendhandle)
Definition: htmsocket.c:173
#define lives_free
Definition: machinestate.h:52
#define lives_memset
Definition: machinestate.h:61
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60