クライアントソケット

■クライアントソケット

クライアントソケットはデータを送信する側のソケットです。

●手順
	①.ポート番号、ホスト名の入力
		サーバー側のポート番号とホスト名を入力します。
		※「サーバー側」のポート番号とホスト名なので注意してください。

	②.WinSockの初期化
		WSAStartup関数でWinSockを初期化します。

	③.ソケットをオープン
		socket関数でソケットをオープンします。

	④.ホスト名からホスト情報を取得する
		gethostbyname関数かgethostbyaddr関数のどちらかを使用して、
		ホスト名からホスト情報を取得します。

	⑤.サーバーへの接続を行う
		connect関数を使用してサーバー側への接続を行います。
		サーバー側の情報はSOCKADDR_IN構造体に設定します。

	⑥.データを送信する
		send関数でサーバーにデータを送信します。
		※通信を終了するまで⑥は繰り返します。

	⑦.ソケットの送受信を停止する
		shutdown関数でソケットの送受信を停止します。

	⑧.ソケットを閉じる
		closesocket関数でソケットを閉じます。

	⑨.WinSockを終了する
		WSACleanup関数でWinSockを終了します。
		
●コード
	#define _WINSOCK_DEPRECATED_NO_WARNINGS
	#include <stdio.h>
	#include <stdlib.h>
	#include <winsock2.h>

	#pragma comment(lib, "Ws2_32.lib")

	void main(void)
	{
		SOCKET client_sock;
		WSADATA wsa_data;
		SOCKADDR_IN sock_addr;
		char buff[1024];
		char server_name[1024];
		HOSTENT *lp_host;
		unsigned int addr;
		int result;
		unsigned short port_no;

		// ①.サーバー側のポート番号
		printf("サーバーのポート番号\n");
		gets_s(buff);
		port_no = atoi(buff);

		// サーバー側のホスト名の入力
		printf("ホスト名(IP、ドメイン、PC名):\n");
		gets_s(server_name);

		// ②.WinSockの初期化
		if (WSAStartup(MAKEWORD(2,2), &wsa_data) != 0)
		{
			printf("WinSockの初期化に失敗しました\n");
			getchar();
			return;
		}

		// ③.ソケットを作成する
		client_sock = socket(AF_INET, SOCK_STREAM, 0);
		if (client_sock == INVALID_SOCKET)
		{
			printf("ソケットオープンエラー\n");
			getchar();
			WSACleanup();
			return;
		}

		// ④.サーバー名からホスト情報を取得
		lp_host = gethostbyname(server_name);
		if (lp_host == NULL)
		{
			// IPアドレスからホスト情報を取得する方法に切り替える
			addr = inet_addr(server_name);
			lp_host = gethostbyaddr((char*)&addr, 4, AF_INET);
		}

		if (lp_host == NULL)
		{
			printf("ホスト情報が取得できませんでした\n");
			getchar();
			WSACleanup();
			return;
		}

		// サーバーへ接続するための準備
		memset(&sock_addr, 0, sizeof(SOCKADDR_IN));
		sock_addr.sin_family = AF_INET;
		sock_addr.sin_port = htons(port_no);
		sock_addr.sin_addr.s_addr = *((unsigned long*)lp_host->h_addr);

		// ⑤.クライアントソケットをサーバーのソケットに接続する
		if (connect(client_sock, (SOCKADDR*)&sock_addr, sizeof(sock_addr)) ==
										SOCKET_ERROR)
		{
			printf("接続エラー\n");
			closesocket(client_sock);
			WSACleanup();
			return;
		}

		while (true)
		{
			printf("送信データ\n");
			gets_s(buff);
			// ⑥.データの送信
			if (strcmp(buff, "end") == 0)
			{
				send(client_sock, buff, (int)strlen(buff), 0);
				break;
			}
			send(client_sock, buff, (int)strlen(buff), 0);
		}

		// ⑦.ソケットの送受信を停止する
		shutdown(client_sock, SD_BOTH);
		// ⑧.ソケットを閉じる
		closesocket(client_sock);
		// ⑨.WinSock終了
		WSACleanup();

		printf("終了\n");
		getchar();

		return;
	}