MyAlbum   Pet
DirectX   openGL   Java   C/C++   STL   C#   Python   Window   ActiveX   SE & Refactoring   Game   Unicode   googleDesktop   Network   Database   Web   php   asp   asp.net   Library   QT   wxWidget   Something to read  
ToDo
zelon's WebAlbum
Google Tools
Google Naver map
ToRearrange
OpenOffice.org
Eclipse
Check W3 validator
Network Programming
e i R f
Anonymous

Contents

1 C#
2 MFC 로 ftp 연결처리
3 win32 send 후킹
4 iocp tip
5 packet structure
6 well-known port number list
7 P2P
8 test tcp client
9 라이브러리
9.1 ACE
10 기초 함수
10.1 ip 주소를 unsigned long 으로
10.2 unsigned long 값을 ip 주소 문자열로
10.3 sin_port 값을 port 번호로
11 Network Library
11.1 winsock2.h 를 include 한 다음 redefinition 오류가 쭈욱 날 때
11.2 UDP Programming
11.2.1 UDP 로 한번에 날아갈 수 있는 패킷의 크기 조사
11.2.2 ip 가 여러개인 컴퓨터에서 UDP bind() 로 P2P 구현
11.2.3 UDP 의 recvfrom() 가 실패하면서 GetLastError() 이 10054(WSAECONNRESET) 를 반한할 때
11.2.4 UDP 로 NAT 뚫기
11.3 TCP Programming
11.3.1 연결된 소켓으로부터 로컬의 ip 얻어오기
11.3.2 전송하기 전에 전송 받으면 성능을 향상 시킬 수 있다
12 암호학
13 기타
13.1 mathopd -- 매우 작고 빠른 HTTP 서버
13.2 picocom -- 정말 간단한 터미널 에뮬레이션 프로그램
13.3 국내 네트워크 품질 기상도 - 평균 up/down 속도
13.4 네트워크 진단툴들
13.5 c10k problem
13.6 네트워크 상의 물리엔진

1 C# #


2 MFC 로 ftp 연결처리 #

	try
	{
		TCHAR ftpServerAddr[] = _T("ftp.com");
		TCHAR ftpUserID[] = _T("zelon");
		TCHAR ftpPwd[] = _T("zelonPWD");

		CInternetSession se;
		CFtpConnection * ftpCon = se.GetFtpConnection(ftpServerAddr, ftpUserID, ftpPwd, INTERNET_INVALID_PORT_NUMBER, TRUE);


		/// C:\boot.ini 파일을 원격 ftp 서버의 boot.ini 라는 파일이름으로 전송한다.
		BOOL ret = ftpCon->PutFile(_T("C:\\boot.ini"), _T("boot.ini"));

		if ( ret == TRUE )
		{
			MessageBox(_T("ok"));
		}
		else
		{
			MessageBox(_T("fail"));
		}
	}
	catch (CInternetException * ex)
	{
		MessageBox(_T("cannot connect ftp"));
	}


3 win32 send 후킹 #


4 iocp tip #


5 packet structure #


6 well-known port number list #


7 P2P #


8 test tcp client #


간단한 패킷을 체크하기 위한 클래스
class CTCPConnect
{
public:

	class IntPacketSplitter
	{
	public:
		virtual size_t getReadNextSize(const char * p, size_t len) = 0;
	};

	CTCPConnect()
	{
		m_socket = INVALID_SOCKET;
	}

	~CTCPConnect()
	{
		disconnect();
	}

	bool connect(const std::string & strServerAddress, int iPort)
	{
		sockaddr_in sockAddr;

		sockAddr.sin_family = AF_INET;
		sockAddr.sin_port = htons(iPort);

		{
			unsigned long l = inet_addr(strServerAddress.c_str());
			if(l == INADDR_NONE)
			{
				struct hostent * hostinfo;
				if((hostinfo = ::gethostbyname(strServerAddress.c_str())) != NULL)
					sockAddr.sin_addr = (*(IN_ADDR *)hostinfo->h_addr_list[0]);
			}
			else sockAddr.sin_addr.s_addr = l;
		}

		m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		if ( 0 == ::connect(m_socket, (const struct sockaddr *)&sockAddr, sizeof(sockAddr)) )
		{
			return true;
		}
		else
		{
			closesocket(m_socket);
			m_socket = INVALID_SOCKET;
		}
		return false;
	}

	void disconnect()
	{
		if ( m_socket != INVALID_SOCKET )
		{
			closesocket(m_socket);
			m_socket = INVALID_SOCKET;
		}
	}

	bool send(const char * p, size_t len)
	{
		if ( m_socket == INVALID_SOCKET )
		{
			_ASSERTE(false);
			return false;
		}

		size_t sendByte = 0;
		int iRet = 0;
		while ( true )
		{
			iRet = ::send(m_socket, &p[sendByte], (int)(len - sendByte), 0);

			if ( iRet <= 0 )
			{
				_ASSERTE(false);
				return false;
			}

			sendByte += iRet;

			if ( sendByte >= len )
			{
				return true;
			}
		}
	}

	bool recvPacket(char * p, size_t len, IntPacketSplitter * packetSplitter)
	{
		size_t totalRecvSize = 0;
		int iRecvSize = 0;

		size_t readNextSize = 0;
		while ( true )
		{
			readNextSize = packetSplitter->getReadNextSize(p, totalRecvSize);

			if ( readNextSize <= 0 )
			{
				/// 패킷이 완성되었을 경우이다.
				_ASSERTE(totalRecvSize > 0);
				return true;
			}

			iRecvSize = ::recv(m_socket, &p[totalRecvSize], (int)readNextSize, 0);

			if ( iRecvSize <= 0 )
			{
				_ASSERTE(false);
				return false;
			}
			totalRecvSize += iRecvSize;
		}
	}

	enum
	{
		MAX_PACKET_SIZE = 1024
	};
protected:

	SOCKET m_socket;
};

class LinePacketSplitter : public CTCPConnect::IntPacketSplitter
{
public:
	/// 다음 읽을 바이트를 돌려준다.
	virtual size_t getReadNextSize(const char * p, size_t len)
	{
		if ( len <= 0 ) return 1;

		/// 마지막의 바이트가 'end line' 이면 패킷이 완성된 것이다.
		if ( p[len-1] == '\n' ) return 0;

		return 1;
	}
};

9 라이브러리 #


10 기초 함수 #


10.1 ip 주소를 unsigned long 으로 #



  • inet_addr("192.168.1.1")

  • 10.2 unsigned long 값을 ip 주소 문자열로 #



  • inet_ntoa(ina.sin_addr)

  • 10.3 sin_port 값을 port 번호로 #



  • ntohs(addr.sin_port)

  • 11 Network Library #


    [http]Redwiki's ACE : C++ Network Programming 의 번역을 한 RedWiki Site 입니다.

    11.1 winsock2.h 를 include 한 다음 redefinition 오류가 쭈욱 날 때 #


    include <winsock2.h> 를 include <windows.h> 보다 먼저해놓자. stdafx.h 파일의 최상에 놓자.

    11.2 UDP Programming #


    11.2.1 UDP 로 한번에 날아갈 수 있는 패킷의 크기 조사 #

    :getsockopt함수로 SO_MAX_MSG_SIZE를 이용해 구할수 있습니다.

    11.2.2 ip 가 여러개인 컴퓨터에서 UDP bind() 로 P2P 구현 #

    ip 가 여러개인 컴퓨터에서는 외부로 연결될 수 있는 ip(서버와 TCP 연결된 socket)를 가지고 bind() 해야한다. 서버로 소켓을 연결한 후, 그 소켓의 ip 를 얻어오고, 그 ip 로 bind() 한다.


    11.2.3 UDP 의 recvfrom() 가 실패하면서 GetLastError() 이 10054(WSAECONNRESET) 를 반한할 때 #


    http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q263/8/23.ASP&NoWebContent=1

    11.2.4 UDP 로 NAT 뚫기 #


    11.3 TCP Programming #


    11.3.1 연결된 소켓으로부터 로컬의 ip 얻어오기 #

    string NetUtil::GetIPFromConnectedSocket(SOCKET connectedSocket)
    {
    	string ret;
    
    	struct sockaddr_in aSockaddr;
    
    	int len=sizeof(sockaddr);
    	int checkError = getsockname(connectedSocket, (struct sockaddr*)&aSockaddr, &len);
    	if ( checkError != 0 )
    	{
    		assert(0);
    	}
    
    	ret = inet_ntoa(aSockaddr.sin_addr);
    	return ret;
    }
    

    연결된 원격의 ip 를 얻어오려면 getsockname() 대신에 getpeername() 을 쓴다.


    11.3.2 전송하기 전에 전송 받으면 성능을 향상 시킬 수 있다 #

    비동기 소켓을 사용하는 경우 네트워크 입출력의 순서는 네트워크 성능 향상에 큰 영향을 미치지 않는다. 이는 패킷이 도착하면 네트워크 시스템은 FD_READ 이벤트를 애플리케이션에 보내고 네트워크 시스템 버퍼가 비어있을 경우 FD_WRITE 이벤트를 보내기 때문에 각각의 이벤트에 대해 애플리케이션은 데이터를 읽거나 쓰면 되기 때문이다. 그러나 블록킹 그리고 논블록킹 모드에서는 네트워크 입출력의 순서를 결정해야한다. 동일한 소켓 상에 동시에 데이터를 보내고 받을 때는 데이터를 보내기 전에 데이터를 읽는 것은 굉장히 중요하다. 이는 블록킹 모드에서 입력 데이터가 가득찬 네트워크 시스템 버퍼에 데이터를 보낼 경우 시스템은 네트워크 시스템 버퍼에서 입력 데이터가 비워질 때까지 블록되기 때문이다. 또한 논블로킹 모드에서는 send() API 호출이 WSAEWOULDBLOCK 값으로 실패하였을 경우 recv() API 를 호출함으로써 성능을 향상시킬 수 있다.


    게임 프로그래머에게 배우는 게임 개발 테크닉(정보문화사)에서 발췌

    12 암호학 #

    http://haje.kaist.ac.kr/~oedalpha/tips/WindowsProgramming/10-tip2-crypto.txt

    13 기타 #


    === 웹 상의 파일 다운 받기 ====

    • URLDownloadToFile()

    13.1 mathopd -- 매우 작고 빠른 HTTP 서버 #

    13.2 picocom -- 정말 간단한 터미널 에뮬레이션 프로그램 #


    13.3 국내 네트워크 품질 기상도 - 평균 up/down 속도 #


    13.4 네트워크 진단툴들 #

    http://info.ahnlab.com/securityinfo/info_view.jsp?seq=6080&category=02

    13.5 c10k problem #


    13.6 네트워크 상의 물리엔진 #