source: trunk/vizservers/nanovis/socket/Socket.cpp @ 884

Last change on this file since 884 was 834, checked in by gah, 16 years ago

Changes for heightmap viewer

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