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
'Programming > Network' 카테고리의 다른 글
열혈 TCP/IP 03-2. 주소정보의 표현 (0) | 2021.02.02 |
---|---|
열혈 TCP/IP 03-1. 소켓에 할당되는 IP주소와 PORT번호 (0) | 2021.02.02 |
열혈 TCP/IP 02-1. 소켓의 프로토콜과 그에 따른 데이터 전송 특성 (0) | 2021.01.31 |
열혈 TCP/IP 1-2. 리눅스 기반 파일 조작하기 (0) | 2021.01.31 |
열혈 TCP/IP 1-1. 네트워크 프로그래밍과 소켓의 이해 (0) | 2021.01.26 |