E D R , A S I H C RSS

Win Sock

Windows Socket API. Win32 API 에 기본적으로 지원한다.

일반적인 버클리 소켓 스타일과 Windows 자체 스타일의 비동기소켓 (윈도우 메세지를 이용하는 방법, IOCP) API 를 제공해준다.

다음은 화일보내고 받기 관련 Winsock API 간단 예제. (옛날 예제삼아 만든 소스여서 직관적이지가 않긴 하군 -_-; 그냥 이해의 차원정도)

보내기 소스 (서버)

서버의 경우 1 user 1 thread 임.


~cpp 
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <process.h>

DWORD WINAPI Threading (LPVOID args)
{
	SOCKET* pSocket = (SOCKET*)args;
	SOCKET socket = *pSocket;
	HANDLE hFileIn;
	char szBuffer[8192]="";
	DWORD nRead, nWrite, i;
	DWORD dwLow, dwHigh;
	int nSended;

	hFileIn = CreateFile ("d:\test.mp3", GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, NULL, NULL);

//	send (*pSocket, "Data", 5, NULL);

	dwLow = GetFileSize (hFileIn, &dwHigh);

	for (i=0;i<dwLow;) {
		SetFilePointer (hFileIn, i, NULL, FILE_BEGIN);
		ReadFile (hFileIn, szBuffer, sizeof (szBuffer), &nRead, NULL);
		nSended = send (socket, szBuffer, nRead, NULL);
		i+= max (0, nSended);

		if (nSended == SOCKET_ERROR) {
			printf ("Error : %d n", WSAGetLastError ());
		}
		else {
			printf ("Current : %d / %d (%d)n", dwLow, i, nSended);
		}

		Sleep (100);
	}

	CloseHandle (hFileIn);


	return 0;
}

int main (void)
{
	WSADATA wsaData;
	sockaddr_in local, from;
	SOCKET socketListen;
	SOCKET socketClient;


	WSACleanup ();
	DWORD dwTemp;

	if (WSAStartup (0x202, &wsaData) == SOCKET_ERROR) {
		printf ("error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}

	local.sin_family = AF_INET;
	local.sin_addr.s_addr = INADDR_ANY;
	local.sin_port = htons (5000);


	socketListen = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (socketListen == INVALID_SOCKET) {
		printf ("create socket error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}


	if (bind (socketListen, (sockaddr *)&local, sizeof (local)) == SOCKET_ERROR) {
		printf ("bind error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}


	if (listen (socketListen, 5) == SOCKET_ERROR) {
		printf ("listen error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}

	BOOL bFlag = TRUE;

	WSAEVENT hEvent = WSACreateEvent ();
	WSAEVENT hEvent2 = WSACreateEvent ();
	WSAEVENT Eventarry[2];

	Eventarry[0] = hEvent;
	Eventarry[1] = hEvent2;


	WSANETWORKEVENTS NetworkEvents;
	DWORD WaitStatus;
	int addlen = sizeof (from);

	WSAEventSelect (socketListen, hEvent, FD_ALL_EVENTS);
	printf ("Waiting.. n");
	while (bFlag) {
		WaitStatus = WSAWaitForMultipleEvents (2, Eventarry, FALSE, 1000, FALSE);

		if (WaitStatus == WSA_WAIT_EVENT_0) {
			if (WSAEnumNetworkEvents (socketListen, hEvent, &NetworkEvents) != 0) {
				printf ("Error.... %dn", GetLastError ());
				bFlag = 0;
			}

			if (NetworkEvents.lNetworkEvents & FD_ACCEPT) {
				if (NetworkEvents.iErrorCode [FD_ACCEPT_BIT] == 0) {
					socketClient = accept (socketListen, (sockaddr *)&from, &addlen);
					printf ("Accepted... !n");
					//send (socketClient, "hugugu~rn", 9, NULL);
					CreateThread (NULL, NULL, Threading, &socketClient, NULL, &dwTemp);
					WSAEventSelect (socketClient, hEvent2, FD_ALL_EVENTS);
				}
			}

		}

		if (WaitStatus == (WSA_WAIT_EVENT_0 + 1) ) {
			if (WSAEnumNetworkEvents (socketClient, hEvent2, &NetworkEvents) != 0) {
				printf ("Error.... %dn", GetLastError ());
//				bFlag = 0;
			}
/*
			if (NetworkEvents.lNetworkEvents & FD_READ) {
				DWORD dwDataReaded;
				char* szBuffer;
				printf ("Data Received... n");
				ioctlsocket (socketClient, FIONREAD, &dwDataReaded);
				szBuffer = (char *)LocalAlloc (LPTR, dwDataReaded);
				recv (socketClient, szBuffer, dwDataReaded, NULL);
				printf ("Data : %s (%d)n", szBuffer, dwDataReaded);
				LocalFree (szBuffer);
			}
*/
			if (NetworkEvents.lNetworkEvents & FD_CLOSE) {
				closesocket (socketClient);
				printf ("closed... !n");
//				bFlag = 0;
			}
		}
	}

	printf ("Program end.. n");

	WSACloseEvent (hEvent);
	WSACloseEvent (hEvent2);
	WSACleanup ();
	return 0;
}

받기 소스 (클라이언트)

~cpp 
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

int main (void)
{
	WSADATA wsaData;
	sockaddr_in local, from;
	SOCKET socketClient;
	SOCKADDR_IN    ServerAddress; //소켓의 주소
	int i=0;

	int nSize;

	WSACleanup ();
	DWORD dwTemp;
	HANDLE hFileOut;
	DWORD nWrite;


	if (WSAStartup (0x202, &wsaData) == SOCKET_ERROR) {
		printf ("error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}

	char szCommand[8]="";

	char szHostName[40];
	gethostname(szHostName, sizeof(szHostName));
	HOSTENT FAR* lphostent = ::gethostbyname(szHostName);
	printf ("IP : %s n",inet_ntoa(*((struct in_addr*)lphostent->h_addr)));


	socketClient = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (socketClient == INVALID_SOCKET) {
		printf ("create socket error.. %dn", WSAGetLastError ());
		WSACleanup ();
		return 0;
	}

	ServerAddress.sin_family = AF_INET;
	//IP주소값. INADDR_ANY는 아무거나입니다. ^^;
	ServerAddress.sin_addr.s_addr = inet_addr( "127.0.0.1" );
	ServerAddress.sin_port = htons( 1002 );  //포트번호

	connect (socketClient, (struct sockaddr*)&ServerAddress, sizeof (ServerAddress));

	WSAEVENT hEvent = WSACreateEvent ();

	WSANETWORKEVENTS NetworkEvents;
	DWORD WaitStatus;

	WSAEventSelect (socketClient, hEvent, FD_ALL_EVENTS);
	hFileOut = CreateFile ("testdata.mp3", GENERIC_WRITE, FILE_SHARE_READ,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);


	while (1) {
		WaitStatus = WSAWaitForMultipleEvents (1, &hEvent, FALSE, 10, FALSE);

		if (WaitStatus == WSA_WAIT_EVENT_0) {
			if (WSAEnumNetworkEvents (socketClient, hEvent, &NetworkEvents) != 0) {
				printf ("Error.... %dn", GetLastError ());
			}

			if (NetworkEvents.lNetworkEvents & FD_CONNECT) {
				if (NetworkEvents.iErrorCode [FD_CONNECT_BIT] == 0) {
					printf ("Connect... !n");
					// TEST_FILE_REQUARE			0xF0
					szCommand[0] = 0xF0;
					send (socketClient, szCommand, 8, NULL);
				}
			}

			if (NetworkEvents.lNetworkEvents & FD_READ) {
				DWORD dwDataReaded;
				char* szBuffer;
				ioctlsocket (socketClient, FIONREAD, &dwDataReaded);
				szBuffer = (char *)LocalAlloc (LPTR, dwDataReaded);
				recv (socketClient, szBuffer, dwDataReaded, NULL);
				WriteFile (hFileOut, szBuffer, dwDataReaded, &nWrite, NULL);
				i+= dwDataReaded;
				printf ("Data Received... %d (%d)n", i, dwDataReaded);

				LocalFree (szBuffer);
			}
		}
	}

	closesocket (socketClient);
	WSACleanup ();


	return 0;
}
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:26
Processing time 0.0210 sec