/
RecSpek.c
326 lines (275 loc) · 8.41 KB
/
RecSpek.c
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/* example code from : timeserv.c */
/* A simple UDP server that sends the current date and time to the client */
/* Last modified: September 20, 2005 */
/* http://www.gomorgan89.com */
/* Link with library file wsock32.lib */
/* multithreading from https://msdn.microsoft.com/en-us/library/windows/desktop/ms682516(v=vs.85).aspx */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#include <unistd.h>
#include <windows.h>
#include <stdio.h>
#include "mesinkar.c"
#define MAX_SEM_COUNT 2
#define THREADCOUNT 2
#define DELAY 500
#define BUFFER_SIZE 40
/** **/
#include "buffer.c"
Tab buf;
int ind = 1;
//#include "buffer.h"
/** **/
WSADATA w; /* Used to open windows connection */
unsigned short port_number; /* Port number to use */
SOCKET sd; /* Socket descriptor of server */
int client_length; /* Length of client struct */
struct sockaddr_in client; /* Information about the client */
char msg; /* Current char msg*/
int nByte =0;
char send_buffer[BUFFER_SIZE] = "XON\r\n"; /* Data to send */
char send_bufferXOFF[BUFFER_SIZE] = "XOFF\r\n";
char buffer[BUFFER_SIZE]; /* Where to store received data */
struct hostent *hp; /* Information about the server */
int server_length; /* Length of server struct */
struct sockaddr_in server; /* Information about the server */
int bytes_received; /* Bytes received from client */
int a1, a2, a3, a4; /* Server address components in xxx.xxx.xxx.xxx form */
int b1, b2, b3, b4; /* Client address components in xxx.xxx.xxx.xxx form */
char host_name[256]; /* Host name of this computer */
int isOn = 0;
int i;
HANDLE ghSemaphore;
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
void usage(void);
void SendXON(){
printf("Send XON...\n");
/* Tranmsit signal XON */
client_length = sizeof(struct sockaddr_in);
if (sendto(sd, send_buffer, (int)strlen(send_buffer) + 1, 0, (struct sockaddr *)&client, client_length) == -1)
{
fprintf(stderr, "Error transmitting data.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
}
void SendXOFF(){
printf("Send XOFF...\n");
/* Tranmsit signal XOFF */
client_length = sizeof(struct sockaddr_in);
if (sendto(sd, send_bufferXOFF, (int)strlen(send_bufferXOFF) + 1, 0, (struct sockaddr *)&client, client_length) == -1)
{
fprintf(stderr, "Error transmitting data.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
}
DWORD WINAPI ProcRcvData( LPVOID lpParam)
{
/* Receive data */
while(1){
client_length = (int)sizeof(struct sockaddr_in);
/* Receive bytes from client */
bytes_received = recvfrom(sd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &client_length);
if (bytes_received < 0)
{
fprintf(stderr, "Could not receive datagram.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
// printf("%s\n", buffer);
if ( (strcmp(buffer, "START\r\n") == 0) )
{
if (recvfrom(sd, (char *)&msg, (int)sizeof(msg), 0, (struct sockaddr *)&client, &client_length) < 0)
{
fprintf(stderr, "Error receiving data.\n");
//closesocket(sd);
//WSACleanup();
//exit(0);
} else {
nByte++;
/* Show message */
printf("Menerima byte ke - %d.\n", nByte);
Add(&buf, msg); // masuk buffer
//printf("Mengonsumsi ke - %d : %c\n", nByte,msg);
}
}
}
closesocket(sd);
WSACleanup();
return 0;
}
DWORD WINAPI ProcWaitSignal( LPVOID lpParam){
while(1){
printf("checking queue\n");
Sleep(1000);
if (NbElmt != 0){
if ((!IsUpper(buf)) && (!IsLower(buf))) {
printf("Mengonsumsi ke - %d : %c\n", ind, buf.TI[ind]);
ind++;
NbElmt--; // konsumsi buffer
} else if (IsUpper(buf)) {
SendXOFF();
printf("Masuk Upper limit\n");
printf("Mengonsumsi ke - %d : %c\n", ind, buf.TI[ind]);
ind++;
NbElmt--; // konsumsi buffer
} else if (IsLower(buf)) {
SendXON();
printf("Masuk Lower limit\n");
// no consume0
}
}
}
return 0;
};
int main (int argc, char **argv)
{
/*** CHECK ARGUMEN VALIDATION ********/
/* Interpret command line */
if (argc == 2)
{
/* Use local address */
if (sscanf(argv[1], "%u", &port_number) != 1)
{
usage();
}
}
else if (argc == 3)
{
/* Copy address */
if (sscanf(argv[1], "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)
{
usage();
}
if (sscanf(argv[2], "%u", &port_number) != 1)
{
usage();
}
}
else
{
usage();
}
/******END ARGUMEN VALIDATION **************/
/* Open windows connection */
if (WSAStartup(0x0101, &w) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
/* Open a datagram socket */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
/* Clear out server struct */
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
/* Set family and port */
server.sin_family = AF_INET;
server.sin_port = htons(port_number);
/* Set address automatically if desired */
if (argc == 2)
{
/* Get host name of this computer */
gethostname(host_name, sizeof(host_name));
hp = gethostbyname(host_name);
/* Check for NULL pointer */
if (hp == NULL)
{
fprintf(stderr, "Could not get host name.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
/* Assign the address */
server.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
server.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
server.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
server.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];
}
/* Otherwise assign it manually */
else
{
server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;
server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;
server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;
server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;
}
/* Bind address to socket */
if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "Could not bind name to socket.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
/* Print out server information */
printf("Binding pada %u.%u.%u.%u : %u\n", (unsigned char)server.sin_addr.S_un.S_un_b.s_b1,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b2,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b3,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b4,
(unsigned short) port_number);
printf("Press CTRL + C to quit\n");
/* Loop and get data from clients */
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(
NULL, // default security attributes
MAX_SEM_COUNT, // initial count
MAX_SEM_COUNT, // maximum count
NULL); // unnamed semaphore
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
// Create 2 worker threads aThread[0] for reading and sending file
aThread[0] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ProcRcvData,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
//case of making thread error
if( aThread[0] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
//aThread[1] for listening XON and XOFF
aThread[1] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ProcWaitSignal,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
//case of making thread error
if( aThread[1] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
// Wait for all threads to terminate
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread and semaphore handles
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
CloseHandle(ghSemaphore);
return 0;
}
void usage(void)
{
fprintf(stderr, "receiver [optional input server_address] port_num\n");
exit(0);
}