orca-sim
UdpAsyncServer.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * This file is part of project ORCA. More information on the project
3  * can be found at the following repositories at GitHub's website.
4  *
5  * http://https://github.com/andersondomingues/orca-sim
6  * http://https://github.com/andersondomingues/orca-software
7  * http://https://github.com/andersondomingues/orca-mpsoc
8  * http://https://github.com/andersondomingues/orca-tools
9  *
10  * Copyright (C) 2018-2020 Anderson Domingues, <ti.andersondomingues@gmail.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 ******************************************************************************/
26 #include "UdpAsyncServer.hpp"
27 
28 #include <iostream>
29 
31 
32 void UdpAsyncServer::Error(UdpAsyncError err) {
33  std::string message = "UdpAsyncErro: ";
34 
35  switch (err) {
37  message = message +
38  "Could not create socket" +
39  "(tips: +exceeded_socket_limit +system_permission).";
40  break;
42  message = message +
43  "Could not bind socket (tips: +address_in_use).";
44  break;
45  default: break;
46  }
47 
48  std::cout << message << std::endl;
49 }
50 
52  if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
54  }
55 
56  int flags = fcntl(socket_fd, F_GETFL);
57  flags |= O_NONBLOCK;
58  fcntl(socket_fd, F_SETFL, flags);
59 
60  // file descriptor set to monitoring for reading
61  FD_ZERO(&original_socket);
62  FD_ZERO(&readfds);
63 
64  // file descriptor set to monitoring for writing
65  FD_ZERO(&writefds);
66 
67  // add the receiving socket to the receiving set
68  FD_SET(socket_fd, &original_socket);
69  FD_SET(socket_fd, &readfds);
70 
71  // add the empty set to the writing monitoring list
72  FD_SET(0, &writefds);
73 
74  // since we got s2 second, it's the "greater", so we use that for
75  // // the n param in select()
76  numfd = socket_fd + 1;
77 
78  // wait until either socket has data ready to be recv()d (timeout 10.5 secs)
79  tv.tv_sec = 1;
80  tv.tv_usec = 500000;
81 
82  server_address.sin_family = AF_INET;
83  server_address.sin_port = htons(port);
84  server_address.sin_addr.s_addr = INADDR_ANY;
85  bzero(&(server_address.sin_zero), 8);
86 
87  address_length = sizeof(struct sockaddr);
88 
89  if (bind(socket_fd, (struct sockaddr *)&server_address,
90  sizeof(struct sockaddr)) == -1) {
92  }
93 }
94 
95 
96 int UdpAsyncServer::Send(char* data, int length) {
97  return sendto(socket_fd, data, length, 0,
98  (struct sockaddr*)&client_address, sizeof(struct sockaddr));
99 }
100 
101 int UdpAsyncServer::Receive(char* data) {
102  // copy the receiving set to the working variable
104 
105  // chech whether the receving set has data
106  int res = select(numfd, &readfds, &writefds, NULL, &tv);
107 
108  switch (res) {
109  case -1:
111  break;
112  case 0:
114  break;
115  default:
116  if (FD_ISSET(socket_fd, &readfds)) {
117  FD_CLR(socket_fd, &readfds);
118  bytes_read = recvfrom(socket_fd, data, MAX_LENGTH, 0,
119  (struct sockaddr *)&client_address, &address_length);
120  return bytes_read;
121  }
122  }
123 
124  return 0;
125 }
126 
128  close(socket_fd);
129 }
130 
UdpAsyncServer(int port)
Default ctor.
This class implements an asynchonous udp server.
struct sockaddr_in server_address client_address
void Error(UdpAsyncError err)
int Send(char *data, int length)
Send a reply to the GDB client.
int Receive(char *data)
Receives data from the GDB client.
#define MAX_LENGTH