Advertisement
Guest User

Untitled

a guest
Mar 30th, 2015
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.63 KB | None | 0 0
  1. /*
  2. * socket demonstrations:
  3. * This is the server side of an "internet domain" socket connection, for
  4. * communicating over the network.
  5. *
  6. * In this case we are willing to wait either for chatter from the client
  7. * _or_ for a new connection.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/time.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <time.h>
  20.  
  21. #ifndef PORT
  22. #define PORT 28700
  23. #endif
  24.  
  25. struct client {
  26. int fd;
  27. struct in_addr ipaddr;
  28. struct client *next;
  29. char name[40];
  30. struct client *fightingwith;
  31. int hitpoints;
  32. int powermoves;
  33. struct client * fightedwith[3];
  34. int histurn;
  35. char keypressed;
  36. };
  37.  
  38. static struct client *addclient(struct client *top, int fd, struct in_addr addr);
  39. static struct client *removeclient(struct client *top, int fd);
  40. static void broadcast(struct client *top, char *s, int size);
  41. int handleclient(struct client *p, struct client *top);
  42.  
  43. int bindandlisten(void);
  44.  
  45. int main(void) {
  46. int clientfd, maxfd, nready;
  47. struct client *p;
  48. struct client *head = NULL;
  49. socklen_t len;
  50. struct sockaddr_in q;
  51. struct timeval tv;
  52. fd_set allset;
  53. fd_set rset;
  54. int i;
  55.  
  56. // time_t t;
  57. // srand((unsigned) time(&t));
  58.  
  59. int listenfd = bindandlisten();
  60. // initialize allset and add listenfd to the
  61. // set of file descriptors passed into select
  62. FD_ZERO(&allset);
  63. FD_SET(listenfd, &allset);
  64. // maxfd identifies how far into the set to search
  65. maxfd = listenfd;
  66.  
  67. while (1) {
  68. // make a copy of the set before we pass it into select
  69. rset = allset;
  70. /* timeout in seconds (You may not need to use a timeout for
  71. * your assignment)*/
  72. tv.tv_sec = 10;
  73. tv.tv_usec = 0; /* and microseconds */
  74.  
  75. nready = select(maxfd + 1, &rset, NULL, NULL, &tv);
  76. if (nready == 0) {
  77. printf("DEBUG MESSAGE:No response from clients in %ld seconds\n",
  78. tv.tv_sec);
  79. continue;
  80. }
  81.  
  82. if (nready == -1) {
  83. perror("select");
  84. continue;
  85. }
  86.  
  87. if (FD_ISSET(listenfd, &rset)) {
  88.  
  89. printf("DEBUG MESSAGE:a new player is joining the arena\n");
  90. len = sizeof(q);
  91. if ((clientfd = accept(listenfd, (struct sockaddr *) &q, &len))
  92. < 0) {
  93. perror("accept");
  94. exit(1);
  95. }
  96. FD_SET(clientfd, &allset);
  97. if (clientfd > maxfd) {
  98. maxfd = clientfd;
  99. }
  100.  
  101. printf("DEBUG MESSAGE:connection from %s\n", inet_ntoa(q.sin_addr));
  102. head = addclient(head, clientfd, q.sin_addr);
  103. char s[512];
  104. sprintf(s, "What is your name?\r\n");
  105. write(clientfd, s, strlen(s));
  106. }
  107.  
  108. for (i = 0; i <= maxfd; i++) {
  109. if (FD_ISSET(i, &rset)) {
  110. for (p = head; p != NULL; p = p->next) {
  111. if (p->fd == i) {
  112. int result = handleclient(p, head);
  113. if (result == -1) {
  114. int tmp_fd = p->fd;
  115. head = removeclient(head, p->fd);
  116. FD_CLR(tmp_fd, &allset);
  117. close(tmp_fd);
  118. }
  119. break;
  120. }
  121. }
  122. }
  123. }
  124. }
  125. return 0;
  126. }
  127.  
  128. int handleclient(struct client *p, struct client *top) {
  129.  
  130. int inbuf = 0;
  131. int where;
  132. char buf[256];
  133. int len;
  134. int room = sizeof(buf);
  135. char *after;
  136. after = buf;
  137.  
  138.  
  139. while ((len = read(p->fd, after, room)) > 0){
  140. inbuf += len;
  141.  
  142. where = find_network_newline(buf, inbuf);
  143.  
  144. if (where >= 0){ // we have a full line
  145. *(buf + where) = '\n';
  146. *(buf + where + 1) = '\0';
  147.  
  148.  
  149.  
  150. //inbuf = inbuf - (where +2);
  151. //memmove(buf, buf + where + 2, sizeof(buf));
  152. }
  153. //room = room - len + where + 2;
  154. after = buf + inbuf;
  155. }
  156.  
  157.  
  158. //char buf[256];
  159. char outbuf[512];
  160. //int len = read(p->fd, buf, sizeof(buf) - 1);
  161.  
  162. if (buf[0] != 'a' && buf[0]!= 'p' && buf[0] != 's'){
  163. char welcomestring[512];
  164. sprintf(welcomestring, "Welcome, %s! Awaiting opponent...\r\n",
  165. buf);
  166. write(p->fd, welcomestring, strlen(welcomestring));
  167. char entersarenastring[512];
  168. sprintf(entersarenastring, "**%s enters the arena**\r\n", buf);
  169. broadcast(top, entersarenastring, strlen(entersarenastring));
  170. }
  171.  
  172. if (len > 0) {
  173. buf[len] = '\0';
  174. if (p->name[0] == 0) {
  175.  
  176. strncpy(p->name, buf, strlen(buf));
  177. p->name[len] = '\0';
  178. p->name[len - 1] = '\0';
  179. p->fightedwith[0] = NULL;
  180. p->fightedwith[1] = NULL;
  181. p->fightedwith[2] = NULL;
  182. }
  183. if (p->fightingwith == NULL) {
  184. struct client *d;
  185. for (d = top; d; d = d->next) {
  186. int didfightwith = 0;
  187. if (d->fightingwith == NULL && d != p && !didfightwith) {
  188. d->fightingwith = p;
  189. p->fightingwith = d;
  190. d->histurn = 1;
  191. p->histurn = 0;
  192. p->hitpoints = (rand() % (30 - 20 + 1) + 20);
  193. p->powermoves = (rand() % (6 - 2 + 1) + 2);
  194. d->hitpoints = (rand() % (30 - 20 + 1) + 20);
  195. d->powermoves = (rand() % (6 - 2 + 1) + 2);
  196. char youengagestring[512];
  197. sprintf(youengagestring, "You engage %s!\r\n", d->name);
  198. write(p->fd, youengagestring, strlen(youengagestring));
  199. sprintf(youengagestring, "You engage %s!\r\n", p->name);
  200. write(p->fightingwith->fd, youengagestring,
  201. strlen(youengagestring));
  202. char s1[256], s2[256], s3[256], s4[256], s5[256];
  203. sprintf(s1, "Your hitpoints: %d\n", p->hitpoints);
  204. write(p->fd, s1, strlen(s1));
  205. sprintf(s2, "Your powermoves: %d\n", p->powermoves);
  206. write(p->fd, s2, strlen(s2));
  207. sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
  208. p->fightingwith->hitpoints);
  209. write(p->fd, s3, strlen(s3));
  210. sprintf(s1, "Your hitpoints: %d\n",
  211. p->fightingwith->hitpoints);
  212. write(p->fightingwith->fd, s1, strlen(s1));
  213. sprintf(s2, "Your powermoves: %d\n",
  214. p->fightingwith->powermoves);
  215. write(p->fightingwith->fd, s2, strlen(s2));
  216. sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
  217. write(p->fightingwith->fd, s3, strlen(s3));
  218.  
  219. if (p->histurn) {
  220. sprintf(s4,
  221. "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  222. write(p->fd, s4, strlen(s4));
  223. sprintf(s5, "Waiting for %s to strike...\r\n",
  224. p->fightingwith->name);
  225. write(p->fightingwith->fd, s5, strlen(s5));
  226. } else {
  227. sprintf(s4,
  228. "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  229. write(p->fightingwith->fd, s4, strlen(s4));
  230. sprintf(s5, "Waiting for %s to strike...\r\n",
  231. p->fightingwith->name);
  232. write(p->fd, s5, strlen(s5));
  233. }
  234. }
  235. }
  236. } else {
  237.  
  238. if (buf[0] == 'a' || buf[0] == 'A'){
  239. char s9[256];
  240. char s1[256], s2[256], s3[256];
  241. int amt = (rand() % (6 - 2 + 1) + 2);
  242. p->fightingwith->hitpoints -= amt;
  243. sprintf(outbuf, "You hit %s for %d damage!\r\n",
  244. p->fightingwith->name, amt);
  245. write(p->fd, outbuf, strlen(outbuf));
  246. sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
  247. p->fightingwith->hitpoints);
  248. write(p->fd, s3, strlen(s3));
  249. sprintf(outbuf, "%s hits you for %d damage!\r\n", p->name,
  250. amt);
  251. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  252. sprintf(s1, "Your hitpoints: %d\n",
  253. p->fightingwith->hitpoints);
  254. write(p->fightingwith->fd, s1, strlen(s1));
  255. sprintf(s2, "Your powermoves: %d\n",
  256. p->fightingwith->powermoves);
  257. write(p->fightingwith->fd, s2, strlen(s2));
  258. sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
  259. write(p->fightingwith->fd, s3, strlen(s3));
  260.  
  261. sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  262. write(p->fightingwith->fd, s9, strlen(s9));
  263. p->histurn = 0;
  264. p->fightingwith->histurn = 1;
  265. p->keypressed = '0';
  266. }
  267. if (buf[0]== 's' || buf[0]== 'S') {
  268. read(p->fd, buf, sizeof(buf) - 1);
  269. sprintf(outbuf, "%s takes a break to tell you:\r\n%s\r\n",
  270. p->name, buf);
  271. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  272. p->histurn = 1;
  273. p->fightingwith->histurn = 0;
  274. p->keypressed = '0';
  275.  
  276. }
  277. if (buf[0] == 'p' || buf[0] == 'P'){
  278. char s9[256];
  279. char s1[256], s2[256], s3[256];
  280. int amt = 3 * (rand() % (6 - 2 + 1) + 2);
  281. if ((rand() % 10) > 4) {
  282. p->fightingwith->hitpoints -= amt;
  283. p->powermoves -= 1;
  284. sprintf(outbuf, "You hit %s for %d damage!\r\n",
  285. p->fightingwith->name, amt);
  286. write(p->fd, outbuf, strlen(outbuf));
  287. sprintf(outbuf, "%s hits you for %d damage!\r\n",
  288. p->name, amt);
  289. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  290. //sprintf(s8,
  291. //"(a)ttack\n(p)owermove\n(s)peak something\r\n");
  292. //write(p->fightingwith->fd, s8, strlen(s8));
  293.  
  294. sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
  295. p->fightingwith->hitpoints);
  296. write(p->fd, s3, strlen(s3));
  297. sprintf(s1, "Your hitpoints: %d\n",
  298. p->fightingwith->hitpoints);
  299. write(p->fightingwith->fd, s1, strlen(s1));
  300. sprintf(s2, "Your powermoves: %d\n",
  301. p->fightingwith->powermoves);
  302. write(p->fightingwith->fd, s2, strlen(s2));
  303. sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
  304. write(p->fightingwith->fd, s3, strlen(s3));
  305.  
  306. sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  307. write(p->fightingwith->fd, s9, strlen(s9));
  308. p->histurn = 0;
  309. p->fightingwith->histurn = 1;
  310. p->keypressed = '0';
  311.  
  312. //
  313.  
  314. } else {
  315. p->powermoves -= 1;
  316. sprintf(outbuf, "Your attack missed!\r\n");
  317. write(p->fd, outbuf, strlen(outbuf));
  318. sprintf(outbuf, "%s's attack missed!\r\n", p->name);
  319. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  320.  
  321. sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
  322. p->fightingwith->hitpoints);
  323. write(p->fd, s3, strlen(s3));
  324. sprintf(s1, "Your hitpoints: %d\n",
  325. p->fightingwith->hitpoints);
  326. write(p->fightingwith->fd, s1, strlen(s1));
  327. sprintf(s2, "Your powermoves: %d\n",
  328. p->fightingwith->powermoves);
  329. write(p->fightingwith->fd, s2, strlen(s2));
  330. sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
  331. write(p->fightingwith->fd, s3, strlen(s3));
  332.  
  333. sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  334. write(p->fightingwith->fd, s9, strlen(s9));
  335. p->histurn = 0;
  336. p->fightingwith->histurn = 1;
  337. p->keypressed = '0';
  338. }
  339. }
  340.  
  341. // Arda's shit
  342. if (!(p->hitpoints > 0)) {
  343. char nomatchstring[512];
  344. sprintf(nomatchstring,
  345. "You are no match for %s. You scurry away...\r\n",
  346. p->fightingwith->name);
  347. write(p->fd, nomatchstring, strlen(nomatchstring));
  348. char givesupstring[512];
  349. sprintf(givesupstring, "%s gives up. You win!\r\n", p->name);
  350. write(p->fightingwith->fd, givesupstring,
  351. strlen(givesupstring));
  352. p->hitpoints = (rand() % (30 - 20 + 1) + 20);
  353. p->powermoves = (rand() % (6 - 2 + 1) + 2);
  354. p->fightingwith->hitpoints = (rand() % (30 - 20 + 1) + 20);
  355. p->fightingwith->powermoves = (rand() % (6 - 2 + 1) + 2);
  356. p->fightingwith = NULL;
  357. p->fightingwith->fightingwith = NULL;
  358. } else {
  359. if ((p->keypressed == 'a' || p->keypressed == 'A')
  360. && p->histurn) {
  361. char s9[256];
  362. int amt = (rand() % (6 - 2 + 1) + 2);
  363. p->fightingwith->hitpoints -= amt;
  364. sprintf(outbuf, "You hit %s for %d damage!\r\n",
  365. p->fightingwith->name, amt);
  366. write(p->fd, outbuf, strlen(outbuf));
  367. sprintf(outbuf, "%s hits you for %d damage!\r\n", p->name,
  368. amt);
  369. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  370. sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  371. write(p->fightingwith->fd, s9, strlen(s9));
  372. p->histurn = 0;
  373. p->fightingwith->histurn = 1;
  374. p->keypressed = '0';
  375. }
  376. if ((p->keypressed == 's' || p->keypressed == 'S')
  377. && p->histurn) {
  378. read(p->fd, buf, sizeof(buf) - 1);
  379. sprintf(outbuf, "%s takes a break to tell you:\r\n%s\r\n",
  380. p->name, buf);
  381. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  382. p->histurn = 1;
  383. p->fightingwith->histurn = 0;
  384. p->keypressed = '0';
  385. }
  386. if ((p->keypressed == 'p' || p->keypressed == 'P')
  387. && p->histurn) {
  388. int amt = 3 * (rand() % (6 - 2 + 1) + 2);
  389. if ((rand() % 10) > 4) {
  390. char s8[256];
  391. p->fightingwith->hitpoints -= amt;
  392. p->powermoves -= 1;
  393. sprintf(outbuf, "You hit %s for %d damage!\r\n",
  394. p->fightingwith->name, amt);
  395. write(p->fd, outbuf, strlen(outbuf));
  396. sprintf(outbuf, "%s hits you for %d damage!\r\n",
  397. p->name, amt);
  398. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  399. sprintf(s8,
  400. "(a)ttack\n(p)owermove\n(s)peak something\r\n");
  401. write(p->fightingwith->fd, s8, strlen(s8));
  402. p->histurn = 0;
  403. p->fightingwith->histurn = 1;
  404. } else {
  405. p->powermoves -= 1;
  406. sprintf(outbuf, "Your attack missed!\r\n");
  407. write(p->fd, outbuf, strlen(outbuf));
  408. sprintf(outbuf, "%s's attack missed!\r\n", p->name);
  409. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  410. p->histurn = 0;
  411. p->fightingwith->histurn = 1;
  412. }
  413. }
  414. if (!(p->keypressed == 's' || p->keypressed == 'S')
  415. && !p->histurn) {
  416. char s5[256];
  417. sprintf(s5, "Waiting for %s to strike...\r\n",
  418. p->fightingwith->name);
  419. write(p->fd, s5, strlen(s5));
  420. p->keypressed = '0';
  421. }
  422. }
  423. }
  424. printf("DEBUG MESSAGE:Received %d bytes: %s", len, buf);
  425. return 0;
  426. } else if (len == 0) {
  427. // socket is closed
  428. printf("DEBUG MESSAGE:Disconnect from %s\n", inet_ntoa(p->ipaddr));
  429. if (p->fightingwith) {
  430. sprintf(outbuf, "--%s dropped. You win!\r\n", p->name);
  431. write(p->fightingwith->fd, outbuf, strlen(outbuf));
  432. p->fightingwith->fightingwith = NULL;
  433. }
  434. sprintf(outbuf, "**%s leaves**\r\n", p->name);
  435. broadcast(top, outbuf, strlen(outbuf));
  436. return -1;
  437. } else { // shouldn't happen
  438. perror("read");
  439. return -1;
  440. }
  441. }
  442.  
  443. /* bind and listen, abort on error
  444. * returns FD of listening socket
  445. */
  446. int bindandlisten(void) {
  447. struct sockaddr_in r;
  448. int listenfd;
  449.  
  450. if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  451. perror("socket");
  452. exit(1);
  453. }
  454. int yes = 1;
  455. if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
  456. == -1) {
  457. perror("setsockopt");
  458. }
  459. memset(&r, '\0', sizeof(r));
  460. r.sin_family = AF_INET;
  461. r.sin_addr.s_addr = INADDR_ANY;
  462. r.sin_port = htons(PORT);
  463.  
  464. if (bind(listenfd, (struct sockaddr *) &r, sizeof r)) {
  465. perror("bind");
  466. exit(1);
  467. }
  468.  
  469. if (listen(listenfd, 5)) {
  470. perror("listen");
  471. exit(1);
  472. }
  473. return listenfd;
  474. }
  475.  
  476. static struct client *addclient(struct client *top, int fd, struct in_addr addr) {
  477. struct client *p = malloc(sizeof(struct client));
  478. if (!p) {
  479. perror("malloc");
  480. exit(1);
  481. }
  482.  
  483. //printf("Adding client %s\n", inet_ntoa(addr));
  484. p->fd = fd;
  485. p->ipaddr = addr;
  486. p->next = top;
  487. p->name[0] = 0;
  488. p->fightingwith = NULL;
  489. top = p;
  490. return top;
  491. }
  492.  
  493. static struct client *removeclient(struct client *top, int fd) {
  494. struct client **p;
  495.  
  496. for (p = &top; *p && (*p)->fd != fd; p = &(*p)->next)
  497. ;
  498. // Now, p points to (1) top, or (2) a pointer to another client
  499. // This avoids a special case for removing the head of the list
  500. if (*p) {
  501. struct client *t = (*p)->next;
  502. printf("Removing client %d %s\n", fd, inet_ntoa((*p)->ipaddr));
  503. free(*p);
  504. *p = t;
  505. } else {
  506. fprintf(stderr, "Trying to remove fd %d, but I don't know about it\n",
  507. fd);
  508. }
  509. return top;
  510. }
  511.  
  512. static void broadcast(struct client *top, char *s, int size) {
  513. struct client *p;
  514. for (p = top; p; p = p->next) {
  515. write(p->fd, s, size);
  516. }
  517. /* should probably check write() return value and perhaps remove client */
  518. }
  519.  
  520. int find_network_newline(char *buf, int inbuf) {
  521. // Step 1: write this function
  522.  
  523. int i;
  524.  
  525. for (i = 0; i < inbuf; i++){
  526. if (buf[i] == '\r'){
  527. return i;
  528. }
  529. }
  530.  
  531. return -1; // return the location of '\r' if found
  532. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement