#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <iostream>
#include <string>
#include <fstream>
#include <thread>

using namespace std;
#pragma comment(lib, "ws2_32.lib")


TCHAR error[100];
// buffer to hold our recived data
char buf[64];
// buffer to hold our sent data
char sendData[64];

extern int a = 0, b = 0, c = 0, d = 0;


class ThrArg {
public:
	int arg1 = 0, arg2 = 0, port;
	char *ip;
	SOCKET client_class;
	DWORD thread_class;
	sockaddr_in from;
	int fromlen = sizeof(from);
};


SOCKET sock;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cleanBuf() //每傳送/接收一次，都要清除
{
	for (int i = 0; i<64; i++)
	{
		buf[i] = NULL;
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cleanSendData() //每傳送/接收一次，都要清除
{
	for (int i = 0; i<64; i++)
	{
		sendData[i] = NULL;
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyin()
{
	while (1)
	{
		cout << "please key in value of a:";
		cin >> a;
		cout << "value of a is " << a << "\n";
		Sleep(5000);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

DWORD WINAPI receive_cmds(LPVOID lpParam)
{

	ThrArg *lpclass1 = (ThrArg *)lpParam;
	char ip_threadINreceive_cmds[17];
	int port_thread = lpclass1->port;




	// set our socket to the socket passed in as a parameter   
	SOCKET current_client = lpclass1->client_class;


	// for error checking 
	int res;
			int *ptr = &a;
	BOOL didRunFlag = 0;

	strcpy(ip_threadINreceive_cmds, lpclass1->ip);


	///////



	

	if (didRunFlag == 0)
	{
		strcpy(sendData, "歡迎跟server連線");
		Sleep(1000);
		send(current_client, sendData, sizeof(sendData), 0);
		cout << "\n已對使用者" << ip_threadINreceive_cmds << " : " << port_thread << "發送歡迎訊息\n";

		cleanBuf();
		cleanSendData();

		didRunFlag = 1;
	}




	// our recv loop




	while (1)
	{
		res = recv(current_client, buf, sizeof(buf), 0);// recv cmds



	if (*ptr >= 1)
	{
		strcpy(sendData, "a的值是 ");
		char buffer[1];
		sprintf(buffer, "%d", a);
		strcat_s(sendData, buffer);
		strcat_s(sendData, " 的唷\n");

		send(current_client, sendData, sizeof(sendData), 0);
		cout << sendData << "\n";
		printf("\n我做完了發送a的值的流程\n");
		cleanBuf();
		cleanSendData();
	}



		if (res <= 0)
		{
			cout << "\n使用者"<< ip_threadINreceive_cmds<<":"<<port_thread<<"已斷線\n";
			closesocket(current_client);
			cleanBuf();
			cleanSendData();
			ExitThread(0);
		}

		else if (strstr(buf, "bye"))
		{ // dissconnected this user
			cout << "\n使用者" << ip_threadINreceive_cmds << ":" << port_thread << "已離線\n";

			strcpy(sendData, "謝謝您，等候您下次使用");
			Sleep(10);
			send(current_client, sendData, sizeof(sendData), 0);

			// close the socket associted with this client and end this thread
			closesocket(current_client);
			ExitThread(0);

			cleanBuf();
			cleanSendData();
		}
		else if (strstr(buf, "1"))
		{ // dissconnected this user
			printf("\n使用者丟1\n");

			strcpy(sendData, "星期一猴子穿新衣");
			Sleep(10);
			send(current_client, sendData, sizeof(sendData), 0);
			printf("\n我有做完發送流程\n");
			cleanBuf();
			cleanSendData();


		}

		else
		{
			cout << "有收到client端傳的消息 但沒有用處\n";
			cout << "res = " << res << "\n";
		}

		res = 0;
		didRunFlag = didRunFlag + 1;

	}




	
		


	
		//else
		//{
		//	strcpy(sendData, buf);
		//	Sleep(10);
		//	send(current_client, sendData, sizeof(sendData), 0);
		//	cout << buf << "\n";
		//	cout << "我有做完發送流程\n";
		//	cleanBuf();
		//	cleanSendData();

		//}


	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int server()
{
	WSADATA wsaData;
	sockaddr_in server;

	// start winsock
	int ret = WSAStartup(0x101, &wsaData); // use highest version of winsock avalible

	if (ret != 0)
	{
		return 0;
	}
	
	// fill in winsock struct ... 
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(4999); // listen on telnet port 4999

								   // create our socket
	sock = socket(AF_INET, SOCK_STREAM, 0);

	if (sock == INVALID_SOCKET)
	{
		closesocket;
		return 0;

	}

	// bind our socket to a port(port 4999) 
	if (::bind(sock, (struct sockaddr*)(sockaddr*)&server, sizeof(server)))
	{
		return 0;
	}
	


	// listen for a connection  
	if (listen(sock, 50) != 0)
	{
		closesocket;
		return 0;

	}



}

void client() {


	ThrArg class1;

	// socket that we snedzrecv data on




	// loop forever 
	while (true)
	{
		// accept connections
		class1.client_class= accept(sock, (struct sockaddr*)&class1.from, &class1.fromlen);


		
			class1.ip = inet_ntoa(class1.from.sin_addr);
			class1.port = htons(class1.from.sin_port);

			cout << "\nserver接收到連線請求，連線ip:" << class1.ip << ",port:" << class1.port << endl;
	
		

		// create our recv_cmds t hread and parse client socket as a parameter
		CreateThread(NULL, 0, receive_cmds, (LPVOID)&class1, 0, &class1.thread_class);
	}

}

int main()
{


	printf("程式開始啦\r\n");

	// our masterSocket(socket that listens for connections)

	cout << "3秒後另外叫一個thread來控制全域變數\n";
	Sleep(3000);
	thread thread1(keyin);

	// for our thread

	server();
	client();

	// shutdown winsock
	closesocket(sock);
	WSACleanup();

	// exit
	return 0;
}