-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNIOclient.cpp
More file actions
executable file
·157 lines (142 loc) · 4.62 KB
/
Copy pathNIOclient.cpp
File metadata and controls
executable file
·157 lines (142 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//
// NON-BLOCKING TCP CLIENT
// =======================
// Non-blocking TCP client library for use with FORTE function blocks.
//
// AUT University - 2019-2020
//
// Version history
// ===============
// 04.01.2020 BRD Original version.
// 07.01.2020 BRD Implemented non-blocking flow control on the sockets.
//
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <string>
#include <fcntl.h>
#include "NIOclient.h"
using std::cout;
using std::string;
using std::to_string;
using std::string;
//
// connectToServer()
// =================
// Establishes an IP connection via a listener socket on a remote server.
//
// serverAddress Fully-qualified network URL for this server
// instance that non-blocking clients can connect
// to. Either a name such as "localhost" or an
// IP address such as "127.0.0.1".
//
// listenerPort The socket port that the server is listening on
// for incoming connections. This is a handover
// type socket. Once a client connects, the server
// will hand over the connection to an individual
// session socket that will manage the traffic for
// that client for the duration of the session.
//
// returns Boolean true if a session can be established. If it
// cannot connect, getlastErrorMessage() returns details
// of the problem.
//
bool NIOclient::connectToServer(string serverAddress, long int listenerPort) {
struct sockaddr_in address, server_addr;
//cout << "Connecting to " << serverAddress << " on port " << to_string(listenerPort) << "\n";
// RA_BRD - need to modularise this, sorting out the CIEC_STRING conversion issue.
//
// FORTE parameter strings have leading and terminating single-quote characters in them
// so remove them from the server address just created.
//long int listenerPort = 0;
//listenerPort = PORT();
// char tempServerAddress[32] = {0};
//serverAddress.toString(tempServerAddress, 32);
//for(int ptr = 1; ptr <= 32; ptr++) {
// tempServerAddress[ptr - 1] = tempServerAddress[ptr];
// if ((ptr > 1 ) && (tempServerAddress[ptr] == '\'')) {
// tempServerAddress[ptr - 1] = '\0';
// break;
// }
//}
lastErrorMessage = "";
haveConnection = false;
if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0 )) < 0) {
lastErrorMessage = "Cannot create socket";
} else {
// Connect to the server.
memset((char *) &address, 0, sizeof(address));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons((uint16_t) listenerPort);
// Convert an IPv4 network address in the format ddd.ddd.ddd.ddd from text to binary form. Use
// AF_INET6 instead of AF_INET if this is an IPv6 address. Note that the second parameter of the
// inet_pton() function requires a character pointer to a string constant. The next line converts
// the serverAddress parameter to a pointer.
const char *ptr_serverAddress = serverAddress.c_str();
if (inet_pton(AF_INET, ptr_serverAddress, &server_addr.sin_addr) <= 0) {
lastErrorMessage = "Invalid address or address not supported";
} else {
if (connect(clientSocket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
lastErrorMessage = "Connection failed";
} else {
int flags = fcntl(clientSocket, F_GETFL, 0);
fcntl(clientSocket, F_SETFL, flags | O_NONBLOCK);
haveConnection = true;
}
}
}
return haveConnection;
}
//
// getLastErrorMessage()
// =====================
// Returns the last error message logged by one of
// the functions in this class.
//
string NIOclient::getLastErrorMessage() {
return lastErrorMessage;
}
//
// isConnected()
// =============
bool NIOclient::isConnected() {
return haveConnection;
}
//
// sendPacket()
// ============
// Sends a packet of data to the remote server that was previously
// connected to using createServerConnection():
//
// msg String to be sent to the server. Since the connection was opened as a stream, there
// no maximum size for this data packet.
//
// returns True if the message was sent successfully.
//
bool NIOclient::sendPacket(string msg) {
if (haveConnection) {
send(clientSocket, msg.c_str(), msg.length(), 0);
return true;
} else {
lastErrorMessage = "Cannot send data packet using sendPacket(): no connection is open.";
return false;
}
}
//
// recvPacket()
// ============
string NIOclient::recvPacket() {
if (haveConnection) {
char buffer[1024] = {0};
read(clientSocket, buffer, 1024);
return buffer;
} else {
lastErrorMessage = "Cannot retrieve data packet using recvPacket(): no connection is open.";
return "";
}
}