source: trunk/packages/vizservers/nanovis/socket/Socket.cpp @ 2822

Last change on this file since 2822 was 2822, checked in by ldelgass, 12 years ago

Const correctness fixes, pass vector/matrix objects by reference, various
formatting and style cleanups, don't spam syslog and uncomment openlog() call.
Still needs to be compiled with -DWANT_TRACE to get tracing, but now trace
output will be output to file in /tmp.

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * ----------------------------------------------------------------------
4 * Implementation of the Socket class.
5 *
6 * ======================================================================
7 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
8 *           Purdue Rendering and Perceptualization Lab (PURPL)
9 *
10 *  Copyright (c) 2004-2006  Purdue Research Foundation
11 *
12 *  See the file "license.terms" for information on usage and
13 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * ======================================================================
15 */
16#include <string.h>
17#include <errno.h>
18#include <fcntl.h>
19
20#include "Socket.h"
21
22ssize_t writen(int fd, void *vptr, size_t n) ;
23ssize_t readn(int fd, void *vptr, size_t n) ;
24
25void error(int status, int err, const char *fmt, ... ){
26  va_list ap;
27  va_start(ap, fmt);
28  //fprintf(stderr, "%s: ", program_name);
29  vfprintf(stderr, fmt, ap);
30  va_end(ap);
31
32  if(err)
33    fprintf(stderr, ":%s (%d)\n", strerror(err), err);
34  if(status)
35    exit(status);
36}
37
38void
39set_address(char *hname, char *sname, struct sockaddr_in *sap, char *protocol)
40{
41    struct servent *sp = NULL;
42    struct hostent *hp;
43    char *endptr;
44    short port;
45   
46    bzero(sap, sizeof(*sap));
47    sap->sin_family = AF_INET;
48   
49    if (hname!=NULL) {
50        if (!inet_aton(hname, &sap->sin_addr)) {
51            hp = gethostbyname(hname);
52            if(hp==NULL) {
53                error(1, 0, "unknown host: %s\n", hname);
54            }
55            sap->sin_addr = *(struct in_addr *) hp->h_addr;
56        }
57    } else {
58        sap->sin_addr.s_addr = htonl(INADDR_ANY);
59    }
60    port = strtol(sname, &endptr, 0);
61    if (*endptr=='\0') {
62        sap->sin_port = htons(port);
63    } else {
64        sp = getservbyname(sname, protocol);
65    }
66    if (sp == NULL) {
67        error(1, 0, "unknown service: %s\n", sname);
68    }
69}
70
71void parse_GET_string(char *_str, char keys[256][256], char values[256][256], int *count)
72{
73  char str[1024];
74  strcpy(str, _str);
75  char * pch_amp;
76
77  //printf ("Splitting string \"%s\" in tokens:\n",str);
78  pch_amp = strtok (str,"&");
79  //return;
80  int k=0;
81  while (pch_amp != NULL)
82  {
83    char keyval[128];
84    strcpy(keyval, pch_amp);
85   
86    char *valptr = strchr(keyval, '=');
87   
88    if (valptr!=NULL)
89    {
90        *valptr='\0';
91    valptr++;
92   
93        strcpy(keys[k], keyval);
94        strcpy(values[k], valptr);
95    }
96    else
97    {
98        strcpy(keys[k], keyval);
99        strcpy(values[k], "");
100    }
101    //printf("Key - :%s:, Value - :%s:\n", keys[k], values[k]);
102    pch_amp = strtok (NULL, "&");
103    k++;
104  }
105  *count = k;
106}
107
108
109
110Socket::Socket() :
111  m_sock ( -1 )
112{
113
114  memset ( &m_addr,
115           0,
116           sizeof ( m_addr ) );
117
118}
119
120Socket::~Socket()
121{
122  if ( is_valid() )
123    ::close ( m_sock );
124}
125
126bool Socket::create()
127{
128  m_sock = socket ( AF_INET,
129                    SOCK_STREAM,
130                    0 );
131
132  if ( ! is_valid() )
133    return false;
134
135
136  // TIME_WAIT - argh
137  int on = 1;
138  if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
139    return false;
140
141
142  return true;
143
144}
145
146
147
148bool Socket::bind ( const int port )
149{
150
151  if ( ! is_valid() )
152    {
153      return false;
154    }
155
156  m_addr.sin_family = AF_INET;
157  m_addr.sin_addr.s_addr = INADDR_ANY;
158  m_addr.sin_port = htons ( port );
159
160  int bind_return = ::bind ( m_sock,
161                             ( struct sockaddr * ) &m_addr,
162                             sizeof ( m_addr ) );
163
164
165  if ( bind_return == -1 )
166    {
167      return false;
168    }
169
170  return true;
171}
172
173
174bool Socket::listen() const
175{
176  if ( ! is_valid() )
177    {
178      return false;
179    }
180
181  //printf("socket:listen:1\n");
182  //fflush(stdout);
183  int listen_return = ::listen ( m_sock, MAXCONNECTIONS );
184  //printf("socket:listen:2\n");
185  //fflush(stdout);
186
187
188  if ( listen_return == -1 )
189    {
190      return false;
191    }
192
193  return true;
194}
195
196
197bool Socket::accept ( Socket& new_socket ) const
198{
199  int addr_length = sizeof ( m_addr );
200  new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
201
202  if ( new_socket.m_sock <= 0 )
203    return false;
204  else
205    return true;
206}
207
208
209bool Socket::send ( const std::string s ) const
210{
211  int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
212  if ( status == -1 )
213    {
214      return false;
215    }
216  else
217    {
218      return true;
219    }
220}
221
222
223bool Socket::send (char* s, int size) const
224{
225  //int status = ::send ( m_sock, s, size, MSG_NOSIGNAL );
226
227  int status = writen(m_sock, s, size);
228  if ( status == -1 )
229    {
230      return false;
231    }
232  else
233    {
234      return true;
235    }
236}
237
238
239int Socket::recv ( std::string& s ) const
240{
241  char buf [ MAXRECV + 1 ];
242
243  s = "";
244
245  memset ( buf, 0, MAXRECV + 1 );
246  int status = ::recv ( m_sock, buf, MAXRECV, 0 );
247
248  if ( status == -1 )
249    {
250      std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
251      return 0;
252    }
253  else if ( status == 0 )
254    {
255      return 0;
256    }
257  else
258    {
259      s = buf;
260      return status;
261    }
262}
263
264
265int Socket::recv (char* s, int size) const
266{
267
268  //int status = ::recv ( m_sock, s, size, 0 );
269  int status = readn( m_sock, s, size);
270
271  if ( status == -1 )
272    {
273      std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
274      return 0;
275    }
276  else if ( status == 0 )
277    {
278      return 0;
279    }
280  else
281    {
282      return status;
283    }
284}
285
286
287bool Socket::connect ( const std::string host, const int port )
288{
289  if ( ! is_valid() ) return false;
290
291  m_addr.sin_family = AF_INET;
292  m_addr.sin_port = htons ( port );
293
294  int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );
295
296  if ( errno == EAFNOSUPPORT ) return false;
297
298  status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
299
300  if ( status == 0 )
301    return true;
302  else
303    return false;
304}
305
306void Socket::set_non_blocking ( const bool b )
307{
308
309  int opts;
310
311  opts = fcntl ( m_sock,
312                 F_GETFL );
313
314  if ( opts < 0 )
315    {
316      return;
317    }
318
319  if ( b )
320    opts = ( opts | O_NONBLOCK );
321  else
322    opts = ( opts & ~O_NONBLOCK );
323
324  fcntl ( m_sock,
325          F_SETFL,opts );
326
327}
328
329ssize_t readn(int fd, void *vptr, size_t n)
330{
331  size_t nleft;
332  ssize_t nread;
333  char* ptr;
334
335  ptr = (char*) vptr;
336  nleft = n;
337
338  while(nleft > 0){
339    if((nread=read(fd, ptr, nleft))<0){
340      if(errno==EINTR)
341        nread = 0;
342      else
343        return(-1);
344    }
345    else if(nread==0){
346      fprintf(stderr, "socket::readn  nread==0\n");
347      break;
348    }
349
350    nleft -= nread;
351    ptr += nread;
352  }
353
354  return (n-nleft);     //return n>=0
355}
356
357
358ssize_t writen(int fd, void *vptr, size_t n)
359{
360  size_t nleft;
361  ssize_t nwritten;
362  const char* ptr;
363
364  ptr = (char*) vptr;
365  nleft = n;
366
367  while(nleft > 0){
368    if((nwritten=write(fd, ptr, nleft))<=0){
369      if(errno==EINTR)
370        nwritten = 0;
371      else
372        return(-1);
373    }
374    nleft -= nwritten;
375    ptr += nwritten;
376  }
377
378  return (n);
379}
Note: See TracBrowser for help on using the repository browser.