-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbattleship_client.c
executable file
·191 lines (169 loc) · 4.69 KB
/
battleship_client.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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <ctype.h>
#include <signal.h>
#include <pthread.h>
void getXAndY(char *bbuffer, char *xVal, char *yVal) {
int offset = 8 - strlen(xVal);
int i = 0;
for (i = 0; i < offset; i++) {
strcat(bbuffer, "0");
}
strcat(bbuffer, xVal);
offset = 8 - strlen(yVal);
i = 0;
for (i = 0; i < offset; i++) {
strcat(bbuffer, "0");
}
strcat(bbuffer, yVal);
}
int main(int argc, char **argv)
{
// Values used for parsing and interpreting cmdline args
int iFlag=0, jFlag=0, bFlag=0, xFlag=0, yFlag=0;
// Result of getopt
int o;
// Socket int pointer
int cli;
// Result of calls to socket function, tested for errors
int testval;
int size;
// Unique client identifier will be concatenated to this value
char path[19] = "./cli_socket_";
// 4 capital letters representing unique identifier for the client/player
char *identifier = NULL;
// X and Y cmdline args
char *xVal = NULL;
char *yVal = NULL;
// Bounded buffer to be sent to server socket
char bbuffer[21]; //4 byte JOIN/BOMB/STAT + 8 byte number + 8 byte number
// + null terminator
struct sockaddr_un srvaddr;
struct sockaddr_un cliaddr;
// ------------------------------------------------------------------------
// PARSE CMD LINE ARGS
// ------------------------------------------------------------------------
// quick error check to see if call is within expected number of arguments
// to make the getopt command arg parsing easier
if (!(argc >= 3)) {
fprintf(stderr,
"Error: too few arguments given to num_client\n");
return 1;
} else if (!(argc <= 8)) {
fprintf(stderr,
"Error: too many arguments given to num_client\n");
return 1;
}
// parse command line options
while ((o = getopt(argc, argv, "i:jbx:y:")) != -1) {
switch (o) {
case 'i':
iFlag = 1;
identifier = optarg;
break;
case 'j':
jFlag = 1;
break;
case 'b':
bFlag = 1;
break;
case 'x':
xFlag = 1;
xVal = optarg;
break;
case 'y':
yFlag = 1;
yVal = optarg;
break;
// Stretch goal: Add s flag and optarg to specify server path
case '?':
if (optopt == 'o')
fprintf(stderr, "-%c needs an argument\n",
optopt);
else if (isprint(optopt))
fprintf(stderr, "Invalid option: -%c\n",
optopt);
else
fprintf(stderr,
"Error parsing cmdline arguments given\n");
return 1;
}
} // end of while loop to parse cmdline args
if (!iFlag) {
fprintf(stderr,
"Error: must specify your unique identifier with -i flag and \
optarg\n");
} else if (jFlag && bFlag) {
fprintf(stderr,
"Error: cannot use both -j and -b simultaneously\n");
return 1;
} else if (bFlag && (!xFlag || !yFlag)) {
fprintf(stderr,
"Error: cannot use -b without specifying both the -x and -y \
argument and their optargs\n");
}
//command line arguments are now parsed and invalid usage has
//been handled.
// ------------------------------------------------------------------------
// SOCKET FUNCTIONALITY
// ------------------------------------------------------------------------
// Initialize client socket and setup struct
cli = socket(AF_UNIX, SOCK_STREAM, 0);
cliaddr.sun_family = AF_UNIX;
strcpy(cliaddr.sun_path, strcat(path, identifier));
size = sizeof(cliaddr);
// Bind client socket to ./cli_socket
unlink(cliaddr.sun_path);
testval = bind(cli, (struct sockaddr *)&cliaddr, size);
if (testval == -1) {
fprintf(stderr, "Error binding client socket\n");
close(cli);
return 1;
}
// Setup srvaddr struct
srvaddr.sun_family = AF_UNIX;
strcpy(srvaddr.sun_path, "./srv_socket");
// Connect to server socket
testval = connect(cli, (struct sockaddr *)&srvaddr, size);
if (testval == -1) {
fprintf(stderr, "Error connecting to server socket\n");
close(cli);
return 1;
}
// Send data to server
if (jFlag == 1) {
strcpy(bbuffer, "JOIN");
// Check if optional x and y solution for joining player was specified
if (xVal != NULL && yVal != NULL) {
getXAndY(bbuffer, xVal, yVal);
// If optional x and y solution for joining player wasn't specified, set to 0.
// server will then assign player a random solution.
} else {
int i = 0;
for (i = 0; i < 16; i++) {
strcat(bbuffer, "0");
}
}
} else if (bFlag == 1) {
strcpy(bbuffer, "BOMB");
// convert command line arg numbers
// to a 8 bit number
getXAndY(bbuffer, xVal, yVal);
}
// Send request to server
testval = send(cli, bbuffer, strlen(bbuffer), 0);
if (testval == -1) {
fprintf(stderr, "Error sending request to server socket\n");
close(cli);
return 1;
}
// Finished interacting with server; close client socket
close(cli);
return 0;
}