ACT-CV - Machine Vision for Cognitive Modeling
tcpserver.cpp
Go to the documentation of this file.
1 // -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; coding: iso-8859-1; -*-
2 
3 /*
4 ACT-CV - Machine Vision for Cognitive Modeling
5 Copyright (c) 2008 Marc Halbruegge
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
22 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #ifndef _WINDOWS
32 // Linux dummy
33 #include "tcpserver.h"
38  if (ActCvServer::singleInstance != nullptr) {
40  ActCvServer::singleInstance=nullptr;
41  }
42  }
44 
46  : running(false) {}
48 void ActCvServer::SetupServerSocket(int portNum){}
51 void ActCvServer::SetData(const char *s) {};
52 void ActCvServer::ThreadFun(void*p) {}
53 
54 #else
55 // Windows version
56 #include <winsock.h>
57 #include <process.h>
58 #include <windows.h>
59 
60 #include <iostream>
61 
62 #include "tcpserver.h"
63 
64 using namespace std;
65 
66 ActCvServer* ActCvServer::singleInstance = nullptr;
67 
69 struct ActCvServerAutoStop {
71  if (ActCvServer::singleInstance != nullptr) {
73  ActCvServer::singleInstance=nullptr;
74  }
75  }
77 
78 
80  : running(false) {
81 
83 
84  threadId = (HANDLE) _beginthread(ThreadFun,0,this);
85 }
86 
88  TerminateThread(threadId,0);
89  closesocket(fd);
90 }
91 
92 void ActCvServer::SetupServerSocket(int portNum) {
93  struct sockaddr_in srv; /* used by bind() */
94  if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
95  perror("socket");
96  return;
97  }
98 
99  BOOL flag = 1;
100  int result = setsockopt(fd, /* socket affected */
101  IPPROTO_TCP, /* set option at TCP level */
102  TCP_NODELAY, /* name of option */
103  (char *) &flag, /* the cast is historical
104  cruft */
105  sizeof(flag)); /* length of option value */
106  if (result < 0) {
107  cerr << "error " << WSAGetLastError() << endl;
108  perror("setsockopt");
109  return;
110  }
111 
112  srv.sin_family = AF_INET; /* use Internet addr family */
113  srv.sin_port = htons(portNum); /* bind socket fd to port 8081*/
114 
115  /* bind: a client may connect to any of my addresses */
116  srv.sin_addr.s_addr = htonl(INADDR_ANY);
117  if(::bind(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) {
118  perror("bind");
119  return;
120  }
121 
122  if(listen(fd, 5) < 0) {
123  perror("listen");
124  return;
125  }
126  printf ("Server wartet auf Verbindungen\n");
127 
128  running=true;
129 }
130 
132  struct sockaddr_in client; /* used by accept() */
133  int client_len = sizeof(client); /* used by accept() */
134  SOCKET conn;
135  conn = accept(fd, (struct sockaddr*) &client, &client_len);
136  if(conn < 0) {
137  throw ServerError("accept");
138  }
139  return conn;
140 }
141 
142 void ActCvServer::WriteData(SOCKET handle) {
143  mutex.Enter();
144 
145  if (&*data == nullptr) {
146  int numBytes=0;
147  if (send(handle, (const char*)&numBytes, sizeof(numBytes), 0) < 0) {
148  mutex.Leave();
149  throw ServerError("write");
150  }
151 
152  } else {
153  int numBytes=static_cast<int>(data->GetSize());
154  if (send(handle, (const char*)&numBytes, sizeof(numBytes), 0) < 0) {
155  mutex.Leave();
156  throw ServerError("write");
157  }
158 
159  if (send(handle, data->GetString(), numBytes, 0) < 0) {
160  mutex.Leave();
161  throw ServerError("write");
162  }
163  }
164 
165  mutex.Leave();
166 }
167 
168 void ActCvServer::SetData(const char *s) {
169  mutex.Enter();
170  data = new GCString(s);
171  mutex.Leave();
172 }
173 
175 void ActCvServer::ThreadFun(void*p) {
176  ActCvServer *_this = (ActCvServer*)p;
177 
178  while(true) { /* Der Server soll laufen bis er abgebrochen wird*/
179  SOCKET newfd;
180  try {
181  newfd = _this->WaitForIncoming();
182  } catch (const ServerError &e) {
183  cerr << e.what() << endl;
184  continue;
185  }
186 
187  char c;
188  int keyCode;
189 
190  for (;;) {
191  try {
192  if (recv(newfd, &c, 1, 0)<1) break;
193  switch(c) {
194  case 'X':
195  _this->WriteData(newfd);
196  break;
197  case 'K':
198  if (recv(newfd, (char*)&keyCode, sizeof(int), 0)<1) break;
199  //
200  _this->keyCodeQueue.push(keyCode);
201  break;
202  default:
203  cerr << "server received unknown message" << endl;
204  }
205  } catch (const ServerError &e) {
206  cerr << e.what() << endl;
207  break;
208  }
209  }
210  closesocket(newfd);
211  }
212  _endthread();
213 }
214 
215 
217 struct WSAAutoStart {
218  WORD wVersionRequested;
219  WSADATA wsaData;
220  int err;
221 
222  WSAAutoStart() {
223  wVersionRequested = MAKEWORD( 2, 2 );
224 
225  WSAStartup(wVersionRequested, &wsaData);
226  }
227  ~WSAAutoStart() {
228  WSACleanup();
229  }
230 } wsaAutoStart;
231 
232 #endif // def _WINDOWS
233 


ACT-CV - Machine Vision for Cognitive Modeling
© 2015 Marc Halbruegge (actcvlibrary@googlemail.com)