package TestCase::Socket {
  use SPVM::Socket;

  sub basic : int () {
    
    # Socket
    my $host = "google.com";
    my $port = 80;
    my $socket = SPVM::Socket->new($host, $port);
    
    my $write_buffer = "GET / HTTP/1.0\r\n\r\n";
    $socket->write((byte[])$write_buffer, length $write_buffer);
    
    my $read_buffer = new byte[100];
    while (1) {
      my $read_length = $socket->read($read_buffer);
      
      if ($read_length < 0) {
        die "Read error";
      }
      
      # print((string)sliceb($read_buffer, 0, $read_length));
      
      if ($read_length < @$read_buffer) {
        last;
      }
    }
    
    return 1;
  }
}

__END__

/**
 * ソケット通信(クライアント側)
 */
class Sample2 {
	void runSample() {

	Socket cSocket = null;
	BufferedReader csInput = null;
	PrintWriter writer = null;
	BufferedReader reader = null;

	try{
		//IPアドレスとポート番号を指定してクライアント側のソケットを作成
		cSocket = new Socket("127.0.0.1", 8765);

		//クライアント側での入力用
		csInput = new BufferedReader
				(new InputStreamReader(System.in));
		
		//クライアント側からサーバへの送信用
		writer = new PrintWriter
				(cSocket.getOutputStream(), true);
		
		//サーバ側からの受取用
		reader = new BufferedReader
				(new InputStreamReader
						(cSocket.getInputStream()));

		//無限ループ　byeの入力でループを抜ける
		String line = null;
		while (true) {
			System.out.println("-------------------");
			System.out.println("偶数の数値を入力して下さい");
			System.out.println("-------------------");

        	line = csInput.readLine();
        	
			//送信用の文字を送信
			writer.println(line);
			
			//byeの入力でループを抜ける
			if (line.equals("bye")) {
				break;
			}
			
			//サーバ側からの受取の結果を表示
			System.out.println
				("サーバーからの回答：" + reader.readLine());
		}
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		try {
			if (reader != null) {
				reader.close();
			}
			if (writer != null) {
				writer.close();
			}
			if (csInput != null) {
				csInput.close();
			}
			if (cSocket != null) {
				cSocket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
        System.out.println("クライアント側終了です");
	}
	}
}


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int
main(int argc, char *argv[])
{
 struct sockaddr_in server;
 int sock;
 char buf[32];
 char *deststr;
 unsigned int **addrptr;

 if (argc != 2) {
	 printf("Usage : %s dest\n", argv[0]);
	 return 1;
 }
 deststr = argv[1];

 sock = socket(AF_INET, SOCK_STREAM, 0);
 if (sock < 0) {
	 perror("socket");
	 return 1;
 }

 server.sin_family = AF_INET;
 server.sin_port = htons(80); /* HTTPのポートは80番です */

 server.sin_addr.s_addr = inet_addr(deststr);
 if (server.sin_addr.s_addr == 0xffffffff) {
	 struct hostent *host;

	 host = gethostbyname(deststr);
	 if (host == NULL) {
		 if (h_errno == HOST_NOT_FOUND) {
			 /* h_errnoはexternで宣言されています */
			 printf("host not found : %s\n", deststr);
		 } else {
			/*
			HOST_NOT_FOUNDだけ特別扱いする必要はないですが、
			とりあえず例として分けてみました
			*/
			printf("%s : %s\n", hstrerror(h_errno), deststr);
		 }
		 return 1;
	 }

	 addrptr = (unsigned int **)host->h_addr_list;

	 while (*addrptr != NULL) {
		 server.sin_addr.s_addr = *(*addrptr);

		 /* connect()が成功したらloopを抜けます */
		 if (connect(sock,
				(struct sockaddr *)&server,
				sizeof(server)) == 0) {
			break;
		 }

		 addrptr++;
		 /* connectが失敗したら次のアドレスで試します */
	 }

	 /* connectが全て失敗した場合 */
	 if (*addrptr == NULL) {
		 perror("connect");
		 return 1;
	 }
 } else {
	 if (connect(sock,
                     (struct sockaddr *)&server, sizeof(server)) != 0) {
		 perror("connect");
		 return 1;
	 }
 }

 /* HTTPで「/」をリクエストする文字列を生成 */
 memset(buf, 0, sizeof(buf));
 snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\n\r\n");

 /* HTTPリクエスト送信 */
 int n = write(sock, buf, (int)strlen(buf));
 if (n < 0) {
	 perror("write");
	 return 1;
 }

 /* サーバからのHTTPメッセージ受信 */
 while (n > 0) {
	 memset(buf, 0, sizeof(buf));
	 n = read(sock, buf, sizeof(buf));
	 if (n < 0) {
		 perror("read");
		 return 1;
	 }

	 /* 受信結果を標準出力へ表示(ファイルディスクリプタ1は標準出力) */
	 write(1, buf, n);
 }

 close(sock);

 return 0;
}
