Missed an important piece of advice
[progcomp2012.git] / judge / manager / network.cpp
1 #include "network.h"
2 #include <stdarg.h>
3
4 using namespace std;
5
6 Network::Network(int newPort) : sfd(-1), port(newPort), file(NULL)
7 {
8         sfd = socket(PF_INET, SOCK_STREAM, 0);
9         if (sfd < 0)
10         {
11                 perror("Network::Network - Error creating TCP socket");
12                 exit(EXIT_FAILURE);
13         }
14 }
15
16 Network::~Network()
17 {
18         if (Valid())
19         {
20                 if (shutdown(sfd, SHUT_RDWR) == -1)
21                 {
22                         perror("Network::~Network - shutting down socket... ");
23                         close(sfd);
24                         sfd = -1;
25                 }
26         }
27         close(sfd);
28 }
29
30 Server::Server(int newPort) : Network(newPort)
31 {
32         struct   sockaddr_in name;
33 //      char   buf[1024];
34 //      int    cc;
35
36         
37         name.sin_family = AF_INET;
38         name.sin_addr.s_addr = htonl(INADDR_ANY);
39         name.sin_port = htons(port);
40
41         if (bind( sfd, (struct sockaddr *) &name, sizeof(name) ) < 0)
42         {
43                 perror("Server::Server - Error binding socket");
44                 close(sfd); sfd = -1;
45                 exit(EXIT_FAILURE);
46         }
47
48         if (listen(sfd,1) < 0)
49         {
50                 perror("Server::Server - Error listening on socket");
51                 close(sfd); sfd = -1;
52                 exit(EXIT_FAILURE);
53         }
54         int psd = accept(sfd, 0, 0);
55         close(sfd);
56         sfd = psd;
57         if (sfd < 0)
58         {
59                 perror("Server::Server - Error accepting connection");
60                 close(sfd); sfd = -1;
61                 exit(EXIT_FAILURE);
62         }
63
64
65
66         /*
67         for(;;) 
68         {
69                 cc=recv(sfd,buf,sizeof(buf), 0) ;
70                 if (cc == 0) exit (0);
71                 buf[cc] = '\0';
72                 printf("message received: %s\n", buf);
73         }
74         */
75 }
76
77 Client::Client(const char * serverAddress, int newPort) : Network(newPort)
78 {
79         struct  sockaddr_in server;
80         struct  hostent *hp;
81
82
83         server.sin_family = AF_INET;
84         hp = gethostbyname(serverAddress);
85         bcopy ( hp->h_addr, &(server.sin_addr.s_addr), hp->h_length);
86         server.sin_port = htons(port);
87
88         if (connect(sfd, (struct sockaddr *) &server, sizeof(server)) < 0)
89         {
90                 fprintf(stderr, "Client::Client - Error connecting to server at address %s: ", serverAddress);
91                 perror("");
92                 close(sfd); sfd = -1;
93                 exit(EXIT_FAILURE);
94         }
95
96
97
98
99         /*
100         for (;;) {
101            send(sfd, "HI", 2,0 );
102            sleep(2);
103         }
104         */
105 }
106
107 /**
108  * Sends a message accross the network
109  * WARNING: Always terminates the message with a newline '\n'
110  * @returns true if the message was successfully sent; false if it was not (ie: the network was not connected!)
111  */
112 bool Network::SendMessage(const char * print, ...)
113 {
114         if (!Valid()) //Is the process running...
115                 return false; 
116
117         if (file == NULL)
118         {
119                 file = fdopen(sfd, "r+");
120                 setbuf(file, NULL);
121         }
122
123         va_list ap;
124         va_start(ap, print);
125
126         if (vfprintf(file, print, ap) < 0 || fprintf(file, "\n") < 0)
127         {
128                 va_end(ap);
129                 return false;
130         }
131         va_end(ap);
132
133         return true;
134 }
135
136 /**
137  * Retrieves a message from the network, waiting a maximum amount of time
138  * @param buffer - C++ string to store the resultant message in
139  * @param timeout - Maximum amount of time to wait before failure. If timeout <= 0, then GetMessage will wait indefinately.
140  * @returns true if the response was recieved within the specified time, false if it was not, or an EOF was recieved, or the process was not running.
141  */
142 bool Network::GetMessage(string & buffer, double timeout)
143 {
144         if (!Valid() || timeout == 0)
145                 return false;
146
147         if (file == NULL)
148         {
149                 file = fdopen(sfd, "r+");
150                 setbuf(file, NULL);
151         }
152
153         assert(&buffer != NULL);
154         GetterThread getterThread(file, buffer);
155         assert(&(getterThread.buffer) != NULL);
156
157         TimerThread timerThread(timeout*1000000);
158
159         getterThread.Start();
160         if (timeout > 0)
161                 timerThread.Start();
162
163         
164         while (!getterThread.Finished())
165         {
166                 if (timeout > 0 && timerThread.Finished())
167                 {
168                         getterThread.Stop();
169                         timerThread.Stop();
170                         return false;
171                 }
172         }
173
174         getterThread.Stop();
175         if (timeout > 0)
176                 timerThread.Stop();
177
178         
179
180         if (buffer.size() == 1 && buffer[0] == EOF)
181                 return false;
182         return true;
183
184
185 }
186

UCC git Repository :: git.ucc.asn.au