[ create a new paste ] login | about

Link: http://codepad.org/aXLhrl2o    [ raw code | fork ]

C, pasted on Dec 14:
//////////////////////////////////////////////////////////////////////
// ishitori.h
//////////////////////////////////////////////////////////////////////

#ifndef _ISHITORI_H_
#define _ISHITORI_H_


#define SERVER_PORT    35000
#define BUFSIZE        1024
#define INIT_STONE_NUM 21
#define STONE_SYMBOL   "●"

int read_stone_num(char *from, int *stone_left);
void print_stone_symbol(int num);
void handle_error(char *func, char *msg);

#endif  /* _ISHITORI_H_ */

//////////////////////////////////////////////////////////////////////
// ishitori.c
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include "ishitori.h"


void handle_error(char *fname, char *msg)
{
  fprintf(stderr, "%s() failed: %s\n", fname, msg);
  exit(1);
}

int read_stone_num(char *from, int *stone_left)
{
  int n = -1;

  print_stone_symbol(*stone_left);
  for (;;) {
    printf("%s: いくつ石を取りますか? (1~3): ", from);
    scanf("%d", &n);
    if (0 < n && n <= 3) {
      if (n > *stone_left) {
        /* 残りの石の数よりも大きい値を取ろうとした場合 */
        n = *stone_left;
      }
      printf("%d個取りました\n", n);
      *stone_left -= n;
      print_stone_symbol(*stone_left);
      break;
    }
    printf("1~3個入力して下さい\n");
  }

  return *stone_left;
}

void print_stone_symbol(int num)
{
  int i;
  if (num < 0) { return; }

  printf("Stones: ");
  for (i = 0; i < num; i++) {
    printf("%s", STONE_SYMBOL);
  }
  printf("[残り%d個]\n", num);

  return;
}

//////////////////////////////////////////////////////////////////////
// ishitori_server.c
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "ishitori.h"


static int setup_server(void);

int main(void)
{
  int connfd = -1;
  int n;
  int stone_left = INIT_STONE_NUM;
  char buf[BUFSIZE] = { 0, };

  connfd = setup_server();

  for (;;) {
    /* サーバが最初に石を取る */
    if (read_stone_num("Server", &stone_left) <= 0) {
      /* サーバの負け */
      printf("Server の負け\n");
      break;
    }
    snprintf(buf, BUFSIZE, "%d", stone_left);
    /* クライアントへ送信 */
    if (write(connfd, buf, strlen(buf)) < 0) {
      close(connfd);
      handle_error("write", strerror(errno));
    }
    /* クライアントから受信 */
    if ((n = read(connfd, buf, BUFSIZE)) > 0) {
      stone_left = atoi(buf);
    }
    else if (n == 0) {
      break;
    }
    else {
      close(connfd);
      handle_error("read", strerror(errno));
    }
  }
  close(connfd);

  return 0;
}

static int setup_server(void)
{
  int listenfd = -1, connfd = -1;
  struct sockaddr_in server_addr, client_addr;
  int client_len = sizeof(client_addr);

  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    handle_error("socket", strerror(errno));
  }

  memset(&server_addr, 0, sizeof(struct sockaddr_in));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(SERVER_PORT);

  if (bind(listenfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0) {
    close(listenfd);
    handle_error("bind", strerror(errno));
  }

  if (listen(listenfd, 1) < 0) {
    close(listenfd);
    handle_error("listen", strerror(errno));
  }

  if ((connfd = accept(listenfd, (struct sockaddr *)&client_addr, &client_len)) < 0) {
    close(listenfd);
    handle_error("accept", strerror(errno));
  }
  close(listenfd);

  return connfd;
}

//////////////////////////////////////////////////////////////////////
// ishitori_client.c
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "ishitori.h"


static int setup_client(char *ip_address);

int main(int argc, char *argv[])
{
  int sockfd = -1;
  int n;
  char buf[BUFSIZE] = { 0, };
  int stone_left = -1;

  if (argc != 2) {
    fprintf(stderr, "usage: ishitori_client serverIP\n");
    exit(1);
  }

  sockfd = setup_client(argv[1]);

  for (;;) {
    /* サーバが最初にデータを送ってくる */
    if ((n = read(sockfd, buf, BUFSIZE)) > 0) {
      stone_left = atoi(buf);
    }
    else if (n == 0) {
      break;
    }
    else {
      close(sockfd);
      handle_error("read", strerror(errno));
    }
    /* 石の個数を標準入力から読み込む */
    if (read_stone_num("Client", &stone_left) <= 0) {
      /* クライアントの負け */
      printf("Client の負け\n");
      break;
    }
    snprintf(buf, BUFSIZE, "%d", stone_left);
    /* サーバへ送信 */
    if ((n = write(sockfd, buf, strlen(buf))) < 0) {
      close(sockfd);
      handle_error("write", strerror(errno));
    }
  }

  close(sockfd);

  return 0;
}

static int setup_client(char *ip_address)
{
  struct sockaddr_in server_addr;
  int sockfd = -1;

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    handle_error("socket", strerror(errno));
  }

  memset(&server_addr, 0, sizeof(struct sockaddr_in));
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(SERVER_PORT);
  if (inet_pton(AF_INET, ip_address, &server_addr.sin_addr) != 1) {
    close(sockfd);
    handle_error("inet_pton", strerror(errno));
  }

  if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0) {
    close(sockfd);
    handle_error("connect", strerror(errno));
  }

  return sockfd;
}


Create a new paste based on this one


Comments: