Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CScommServer.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifdef WIN32
26 # define _CRT_SECURE_NO_DEPRECATE // vs8
27 # pragma warning (disable: 4251) // STL MAP DLL warning noise (JW)
28 #endif
29 
30 #include "CScommServer.hh"
31 
32 #ifdef WIN32
33 # include <winsock.h>
34 //# include <winsock2.h>
35 #else //WIN32
36 # include <sys/poll.h>
37 # include <netinet/in.h>
38 # include <sys/socket.h>
39 # include <netdb.h>
40 # include <unistd.h>
41 # include <netinet/tcp.h>
42 #endif //WIN32
43 
44 #include <Base/Debug/Error.hh>
45 #include <sys/types.h>
46 #include <errno.h>
47 #include <cstdio>
48 #include <cstdlib>
49 #include <cstring>
50 
51 using namespace std;
52 using namespace BIAS;
53 
54 CScommServer::CScommServer(bool threaded) : CScommBase(threaded)
55 {
56  isServer_=true;
57  terminateListener_=false;
58  listenThreadActive_=false;
59 }
60 
61 
63 {
64  if (listenThreadActive_) {
65  terminateListener_=true;
66  // pthread_exit(pthreadListener_,NULL);
67  listenThreadActive_=false;
68  }
69 }
70 
72 {
73  if (listenThreadActive_) return;
74  int res;
75  BIASDOUT(D_CS_LISTENER,mygetpid() << ": Starting listener on port " <<
76  connectPort_);
77  terminateListener_ = false;
78  res = pthread_create(&pthreadListener_, NULL, listenthread, this);
79  if (res!=0) {
80  BIASERR("cant crete listen thread");
81  }
83 }
84 
85 void CScommServer::WaitForConnections(unsigned int port) {
86  connectPort_= port;
88 }
89 
90 void *BIAS::listenthread(void *data)
91 {
92  struct sockaddr_in client_addr;
93 
94 #ifdef WIN32
95  int clilen;
96 #else //WIN32
97  socklen_t clilen;
98 #endif //WIN32
99 
100  int listenfd, newclientfd;
101  int res;
102  CScommServer *comm;
103 
104  comm = (CScommServer*)data;
105 
106  listenfd=(int)socket (AF_INET, SOCK_STREAM, 0);
107 
108  // int reuse_option = 1;
109  // res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
110  // (char*) &reuse_option, sizeof(reuse_option));
111  // if (res<0) {
112  // BIASERR("Erorr:'"<<strerror(errno)<<"' while setting socket option:"
113  // <<comm->connectPort_);
114  // pthread_exit(NULL);
115  // }
116 
117  memset(&client_addr, 0, sizeof(client_addr));
118  client_addr.sin_family = AF_INET;
119  client_addr.sin_addr.s_addr = INADDR_ANY;
120 
121  //turn off Nagle-Algorithm for immediatly sending short msgs
122  bool * flag = new bool(true);
123  int length = sizeof(bool);
124  setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, (char *) flag, length);
125 
126  int maxTries=1;
127  if (comm->portChange_)
128  maxTries=10;
129  int tries=0;
130  res=-1;
131  while ((res<0) && tries<maxTries) {
132  client_addr.sin_port = htons((u_short) comm->connectPort_);
133  // Use ::bind to distinguish C socket bind from C++ std::bind
134  res = ::bind(listenfd,(struct sockaddr *) &client_addr,
135  sizeof(client_addr));
136  tries++;
137  if (res<0) {
138  cout<<"res<0"<<" Erorr:'"<<strerror(errno)<<endl;
139  comm->connectPort_++;
140  }
141  }
142 
143  if ( (res<0) && (tries>maxTries) ) {
144  BIASERR("Erorr:'"<<strerror(errno)<<"' for ports:"
145  <<D_CS_DEFAULT_PORT<<" to "<<comm->connectPort_);
146  pthread_exit(NULL);
147  }
148 
149  if (comm->verbose_)
150  comm->verboseOut_<<mygetpid()
151  <<": Listening on port "<<comm->connectPort_<<endl;
152 
153  while (!comm->terminateListener_) {
154  // now listen
155  res = listen(listenfd,1);
156  if (res <0) {
157  perror("Listening for clients");
158 #ifdef WIN32
159  Sleep(1000);
160 #else //WIN32
161  sleep(1);
162 #endif //WIN32
163  break;
164  }
165  clilen = sizeof(client_addr);
166  newclientfd = (int)accept(listenfd,(struct sockaddr *)&client_addr,&clilen);
167 
168  if ((comm->GetDebugLevel() & D_CS_LISTENER) >0)
169  cout << mygetpid() << ": Listener got something"<<endl;
170 
171  if (newclientfd < 0)
172  perror("Error accepting connection from client");
173  else {
174  res = comm->AcceptConn_(newclientfd);
175  // all channels are busy, close and wait for a while
176  if (res <0) {
177 #ifdef WIN32
178  closesocket(newclientfd);
179  Sleep(1000);
180 #else //WIN32
181  close(newclientfd);
182  sleep(1);
183 #endif //WIN32
184  }
185  else
186  if ((comm->GetDebugLevel() & D_CS_LISTENER) >0)
187  cout <<"Client accepted, relistening"<<endl;
188  }
189  }
190  pthread_exit(NULL);
191 
192  return NULL;
193 }
194 
void * listenthread(void *data)
these are wrapper to comply to the pthread_create() interface
void WaitForConnections(unsigned int port=D_CS_DEFAULT_PORT)
Init function, returns instantly and enables the server to accept connections on the given port ...
int GetDebugLevel() const
Definition: Debug.hh:332
class for sending/receiving data between clients and serversOnly registered msgs will be accepted at ...
Definition: CScommServer.hh:55
this class CScomm (ClientServer communciation) handles data comunication via TCP/IP for one server an...
Definition: CScommBase.hh:73
std::ostream verboseOut_
Definition: CScommBase.hh:291
pthread_t pthreadListener_
Definition: CScommServer.hh:78
friend void * listenthread(void *data)
these are wrapper to comply to the pthread_create() interface
int AcceptConn_(int fd)
Definition: CScommBase.cpp:968