/*minitalk サーバプログラム*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>


int CanIRecv(int fd){ 
	fd_set fdset;
	struct timeval timeout;
	FD_ZERO( &fdset ); 
	FD_SET( fd , &fdset );
	timeout.tv_sec = 0; 
	timeout.tv_usec = 0;
	return select( fd+1 , &fdset , NULL , NULL , &timeout );
}


int main(int argc, char *argv[])
{
	int srv_sock, sock, port;
	struct sockaddr_in srv_addr, cli_addr;
	int addrlen, sendlen, recvlen;
	char buf[256];

	/* ポート番号を引数から取得 */
	port = strtol(argv[1], NULL, 10);

	/* ソケットの作成 */
	srv_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (srv_sock < 0) {
		perror("cannot create socket");
		exit(-1);
	}

	/* サーバとしてバインド */
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_port = htons(port);
	srv_addr.sin_addr.s_addr = INADDR_ANY;
	if (bind(srv_sock, (struct sockaddr*)&srv_addr, sizeof(srv_addr)) < 0) {
		perror("bind failed");
		exit(-1);
	}

	/* 待ち受け人数を1人に設定 */
	listen(srv_sock, 1);

	/* クライアントからの接続を受け付ける */
	addrlen = sizeof(cli_addr);
	sock = accept(srv_sock, (struct sockaddr*)&cli_addr, &addrlen);
	if (sock == -1) {
		perror("accept failed");
		exit(-1);
	}
	printf("connected\n");

	/* これ以上クライアントを受け付けないので、サーバのソケットを閉じる */
	close(srv_sock);

	/* 実際の通信 */
	while (feof(stdin) == 0) {
		
		if(CanIRecv(0)){
			/* 標準入力からキーボード入力された文字を読み込む */
			printf("message : ");
			fgets(buf, sizeof(buf), stdin);
			/* 読み込んだ文字をソケットに書き込む */
			sendlen = write(sock, buf, strlen(buf) + 1);
			if (sendlen < 0) {
				perror("cannot send a message");
			}
		}

		
		if (CanIRecv(sock)) {
			/* ソケットからのデータを読み込む */
			recvlen = read(sock, buf, sizeof(buf));
			if (recvlen <= 0) {
				/* クライアント側が EOF */
				break;
			}
			printf(">> %s", buf);
		}
		
		
	}
	close(sock);
}

