source: trunk/gui/vizservers/nanovis/socket/Socket.cpp @ 226

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