728x90

윈속

- Windows Socket API

- 윈도우 운영체제 기반의 네트워크 프로그램 개발을 위한 API

- 윈속을 사용하기 위해서는 ws2_32.lib를 링크하고 winsock2.h 헤더파일을 사용

- 초기화 : 윈속 관련 라이브러리 사용을 위해 초기화 진행

    -> wVersionRequested : 윈속의 버전 정보 전달

    -> lpWSAData : WSADATA 구조체 변수의 주소 값 전달

#include <winsock2.h>

int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

- 해제 : 라이브러리 해제 함수

#include <winsock2.h>

int WSACleanup(void);

 

윈도우 기반의 소켓 관련 함수

- 전에 설명한 함수들은 리눅스 기반의 함수들이지만 차이는 거의 없음

- 소켓 생성

    -> 리눅스의 경우 성공시 파일 디스크립터를 반환하지만 윈도우에서는 핸들(HANDLE)이라 함

#include <winsock2.h>

SOCKET socket(int af,int type,int protocol);

- bind

#include <winsock2.h>

int bind(SOCKET s, const struct sockaddr* name, int namelen);

- listen

#include <winsock2.h>

int listen(SOCKET s, int backlog);

- accept

#include <winsock2.h>

SOCKET accept(SOCKET s, struct sockaddr* addr, int* addrlen);

- connect

#include <winsock2.h>

int connect(SOCKET s, const struct sockaddr* name, int namelen);

- closesocket : 리눅스는 소켓을 파일로 간주하기 때문에 close를 호출하지만 윈도우는 구분하여 사용하기 때문에 별도의 close 함수를 제공

#include <winsock2.h>

int closesocket(SOCKET s);

- 데이터 송신

#include <winsock2.h>

int send(SOCKET s, const char* buf, int len, int flag);

- 데이터 수신

#include <winsock2.h>

int rev(SOCKET s, const char* buf, int len, int flags);

- 서버 예제 코드

    -> 리눅스와 크게 다를것이 없음

int main(int argc, char* argv[])
{
	WSADATA	wsaData;
	SOCKET hServSock, hClntSock;		// 서버, 클라이언트 소켓	
	SOCKADDR_IN servAddr, clntAddr;		// 주소 정보

	int szClntAddr;
	char message[]="Hello World!";

	if(argc!=2) 
	{
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
  
	if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)		// 라이브러리 초기화
		ErrorHandling("WSAStartup() error!"); 
	
	hServSock=socket(PF_INET, SOCK_STREAM, 0);		// 소켓 생성
	if(hServSock==INVALID_SOCKET)
		ErrorHandling("socket() error");
  
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
	servAddr.sin_port=htons(atoi(argv[1]));
	
	if(bind(hServSock, (SOCKADDR*) &servAddr, sizeof(servAddr))==SOCKET_ERROR)	// 주소정보 할당
		ErrorHandling("bind() error");  
	
	if(listen(hServSock, 5)==SOCKET_ERROR)		// 연결 수락 상태
		ErrorHandling("listen() error");

	szClntAddr=sizeof(clntAddr);    	
	hClntSock=accept(hServSock, (SOCKADDR*)&clntAddr,&szClntAddr);		// 연결 수락
	if(hClntSock==INVALID_SOCKET)
		ErrorHandling("accept() error");  
	
	send(hClntSock, message, sizeof(message), 0);		// 데이터 송신
	closesocket(hClntSock);		// 소켓 소멸
	closesocket(hServSock);
	WSACleanup();				// 라이브러리 소멸
	return 0;
}

- 클라이언트 예제 코드

int main(int argc, char* argv[])
{
	WSADATA wsaData;
	SOCKET hSocket;
	SOCKADDR_IN servAddr;

	char message[30];
	int strLen;

	if(argc!=3)
	{
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}

	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)		// 라이브러리 초기화
		ErrorHandling("WSAStartup() error!");  
	
	hSocket=socket(PF_INET, SOCK_STREAM, 0);		// 소켓 생성
	if(hSocket==INVALID_SOCKET)
		ErrorHandling("socket() error");
	
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr=inet_addr(argv[1]);
	servAddr.sin_port=htons(atoi(argv[2]));
	
	if(connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr))==SOCKET_ERROR)		// 연결
		ErrorHandling("connect() error!");
 
	strLen=recv(hSocket, message, sizeof(message)-1, 0);		// 데이터 수신
	if(strLen==-1)
		ErrorHandling("read() error!");
	printf("Message from server: %s \n", message);  

	closesocket(hSocket);		// 소켓 소멸
	WSACleanup();				// 라이브러리 소멸
	return 0;
}
728x90

+ Recent posts