Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / ColonetClient / Server.cpp @ 13

History | View | Annotate | Download (6.45 KB)

1 13 emarinel
/**
2
 *
3
 *  @author Jason Knichel
4
 *
5
 * 2/15/07
6
 */
7
8
#include "includes/Server.h"
9
10
#include <sys/types.h>
11
#include <sys/socket.h>
12
#include <stdio.h>
13
#include <string.h>
14
#include <netinet/in.h>
15
#include <unistd.h>
16
#include <netdb.h>
17
#include <stdlib.h>
18
#include "../lib/colonet_defs.h"
19
20
21
Server::Server(char * serverAddress, char * port)
22
{
23
  if (!serverAddress)
24
    {
25
      //TODO: log error message here
26
      error = 1;
27
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Server address was null.");
28
      return;
29
    }
30
31
  struct hostent * host = gethostbyname(serverAddress);
32
  if (!host)
33
    {
34
      //TODO: log error message here
35
      error = 1;
36
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Could not look up IP address from server address.");
37
      return;
38
    }
39
40
  int portNum = 0;
41
  char * endPtr = NULL;
42
  portNum = strtol(port, &endPtr, 10);
43
  if (port[0] == '\0' || *endPtr != '\0')
44
    {
45
      //TODO: log error message here
46
      error = 1;
47
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "\nThe specified port was invalid.\n");
48
      return;
49
    }
50
  if (portNum < MIN_PORT || portNum > MAX_PORT)
51
    {
52
      //TODO: log error message here
53
      error = 1;
54
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "\nThe port must be between %d and %d inclusive.\n", MIN_PORT, MAX_PORT);
55
      return;
56
    }
57
58
  //TODO: test this to make sure the string host->h_addr is the 4 byte ip
59
  // and not a string in dot notation
60
  int ipAddress = ntohl(atoi(host->h_addr));
61
62
  initializeServer(ipAddress, (unsigned short)portNum);
63
}
64
65
Server::Server (int ipAddress, unsigned short port)
66
{
67
  initializeServer(ipAddress, (unsigned short)port);
68
}
69
70
71
int Server::sendMsg(char * message)
72
{
73
  if (!message)
74
    {
75
      error = 1;
76
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Message was null when trying to send a message.");
77
      return ERROR_SERVER_PARAMETER_NULL;
78
    }
79
80
  if (strlen(message) > MAX_COMMAND_LEN)
81
    {
82
      error = 1;
83
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Message was too long.");
84
      return ERROR_SERVER_MESSAGE_LENGTH;
85
    }
86
87
  if (serverSocket < 0)
88
    {
89
      error = 1;
90
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The socket was not a valid file descriptor.");
91
      return ERROR_SERVER_SOCKET;
92
    }
93
94
  char * sentPoint = message;
95
  int needToSend = strlen(sentPoint);
96
97
  if (sentPoint[needToSend-1] != '\n')
98
    {
99
      if (needToSend == MAX_COMMAND_LEN-1)
100
        {
101
          error = 1;
102
          snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The message was not terminated by a newline and there was no room to add one.");
103
          return ERROR_NO_NEWLINE;
104
        }
105
      else
106
        {
107
          sentPoint[needToSend] = '\n';
108
          sentPoint[needToSend+1] = '\0';
109
          needToSend++;
110
        }
111
    }
112
  while(needToSend > 0)
113
    {
114
      int sent = write(serverSocket, sentPoint, needToSend);
115
      if (sent < 0)
116
        {
117
          error = 1;
118
          snprintf(errorMsg, MAX_ERROR_MSG_LEN, "There was an error when trying to send the message to the server.");
119
          return ERROR_SERVER_SENDING;
120
        }
121
      needToSend -= sent;
122
    }
123
124
  return 1;
125
}
126
127
int Server::recvMessagesFromServer()
128
{
129
  char message[READ_BUFFER_SIZE];
130
  int maxCanRead = READ_BUFFER_SIZE - readBufferLength;
131
132
  if (maxCanRead > 0)
133
    {
134
      fd_set readSet;
135
      FD_ZERO(&readSet);
136
      FD_SET(serverSocket, &readSet);
137
138
      struct timeval t;
139
      memset(&t, 0, sizeof(struct timeval));
140
141
      select (serverSocket+1, &readSet, NULL, NULL, &t);
142
143
      if (!(FD_ISSET(serverSocket, &readSet)))
144
        {
145
          return 1;
146
        }
147
148
      printf("Before read.\n");
149
      int numRead = read(serverSocket, message, maxCanRead);
150
      printf("After read.\n");
151
152
      if (numRead < 0)
153
        {
154
          error = 1;
155
          snprintf(errorMsg, MAX_ERROR_MSG_LEN, "There was an error reading from the server.");
156
          return ERROR_SERVER_READING;
157
        }
158
      memcpy(readBuffer+readBufferLength, message, numRead);
159
      readBufferLength += numRead;
160
    }
161
162
  return 1;
163
}
164
165
int Server::getMsg(char * buffer, int bufferLen)
166
{
167
  if (!buffer)
168
    {
169
      error = 1;
170
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The buffer given to getMsg was null.");
171
      return ERROR_SERVER_PARAMETER_NULL;
172
    }
173
  if (bufferLen < 0 || bufferLen > MAX_RESPONSE_LEN)
174
    {
175
      error = 1;
176
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The buffer length given to getMsg was invalid.");
177
      return ERROR_SERVER_BUFFER_LENGTH;
178
    }
179
180
  int len = -1;
181
  int i;
182
  for (i = 0; i < readBufferLength; i++)
183
    {
184
      if (readBuffer[i] == '\n')
185
        {
186
          len = i+1;
187
          break;
188
        }
189
    }
190
191
  if (len == -1)
192
    {
193
      //no message found in buffer
194
      return 0;
195
    }
196
197
  if (len > MAX_RESPONSE_LEN)
198
    {
199
      //there was a message in the buffer but it was too long
200
      memmove(readBuffer, readBuffer+len, readBufferLength - len);
201
      readBufferLength -= len;
202
      error = 1;
203
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The next message in the buffer was too long.  Removing message from buffer.");
204
      return ERROR_SERVER_MESSAGE_TOO_LONG;
205
    }
206
207
  if (len > bufferLen)
208
    {
209
      error = 1;
210
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "The next message is longer than the buffer it is trying to be stored in.  Leaving message in queue.");
211
      return ERROR_SERVER_NOT_ENOUGH_ROOM;
212
    }
213
214
  //this copies the newline over also into the buffer
215
  memcpy(buffer, readBuffer, len);
216
  memmove(readBuffer, readBuffer+len, readBufferLength - len);
217
  readBufferLength -= len;
218
219
  return 1;
220
}
221
222
int Server::isError()
223
{
224
  return error;
225
}
226
227
char * Server::getErrorMsg()
228
{
229
  return errorMsg;
230
}
231
232
void Server::clearError()
233
{
234
  memset(errorMsg, 0, MAX_ERROR_MSG_LEN);
235
  error = 0;
236
}
237
238
239
240
/******************
241
 *  Private Methods
242
 *****************/
243
244
//assumes ipAddress and port are in host format
245
void Server::initializeServer(int ipAddress, unsigned short port)
246
{
247
  serverSocket = socket(AF_INET, SOCK_STREAM, 0);
248
  if (serverSocket < 0)
249
    {
250
      //TODO: implement logging system and log error message here
251
      error = 1;
252
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Could not create a socket.");
253
      return;
254
    }
255
256
  struct sockaddr_in addr;
257
  memset (&addr, 0, sizeof(struct sockaddr_in));
258
  addr.sin_family = AF_INET;
259
  addr.sin_addr.s_addr = htonl(ipAddress);
260
  addr.sin_port = htons(port);
261
262
  if (connect(serverSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
263
    {
264
      //TODO: log error message here
265
      close(serverSocket);
266
      error = 1;
267
      snprintf(errorMsg, MAX_ERROR_MSG_LEN, "Could not connect to server.");
268
      return;
269
    }
270
271
  readBufferLength = 0;
272
273
  clearError();
274
}