/* 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 );
}


void get_ipaddr(const char *hostname, struct in_addr *paddr)
{
	struct hostent *phost;

	/* まず文字列がホスト名と仮定して検索 */
	phost = gethostbyname(hostname);
	if (phost != NULL) {
		memcpy(paddr, phost->h_addr_list[0], sizeof(struct in_addr));
		return;
	}

	/* 検索に失敗した場合、文字列を IP アドレスとして検索 */
	paddr->s_addr = inet_addr(hostname);
}

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

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

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

	/* サーバとしてバインド */
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_port = htons(port);
	get_ipaddr(servhost, &srv_addr.sin_addr);
	if (connect(sock, (struct sockaddr*)&srv_addr, sizeof(srv_addr)) < 0) {
		perror("connect failed");
		exit(-1);
	}
	printf("connected\n");
	printf("waiting a message from server... \n");

	/* 実際の通信 */
	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);
}

