#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib,"wsock32.lib")
#define PORT 2020
int main(void){
// WSAStartup
// 소켓버전을 받음
WSADATA wsaData;
if(WSAStartup(WINSOCK_VERSION, &wsaData) != 0 ){
printf("WSAStartup 실패, 에러코드 = %u\n",WSAGetLastError());
return false;
}else{
printf("WSAStartup 성공\n");
}
// socket
// 소켓디스크립터
SOCKET s;
// TCP/IP용 소켓생성
s=socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET){
printf("소켓 생성 실패, 에러코드 : %u\n",WSAGetLastError());
WSACleanup();
return false;
}else{
printf("소켓 생성 성공\n");
}
// setsockopt (SO_RCVBUF)
// 1Mbytes 의 수신버퍼
int nBufLen = 1048576;
// 옵션 변수의 길이
int size =sizeof(int);
if( setsockopt(s, SOL_SOCKET,SO_RCVBUF, (char*)&nBufLen, size) != 0){
printf("소켓 수신 버퍼 크기 설정 실패, 에러코드 = %u\n",WSAGetLastError());
//소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("소켓 수신 버퍼 크기 설정 성공\n");
}
// bind
SOCKADDR_IN addr_bind;
// AF_INET 체계임을 명시
addr_bind.sin_family = AF_INET;
// 설정된 포트를 사용
addr_bind.sin_port = htons(PORT);
// 기본네트워크 카드 설정
addr_bind.sin_addr.s_addr = htons(ADDR_ANY);
if( bind(s, (LPSOCKADDR)&addr_bind, sizeof(addr_bind)) == SOCKET_ERROR){
printf("바인드 실패, 에러코드 = %u\n",WSAGetLastError());
// 소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("바인드 성공\n");
}
// listen
if( listen(s, SOMAXCONN) == SOCKET_ERROR){
printf("접속 대기 큐 설정 실패, 에러코드 = %u\n",WSAGetLastError());
// 소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("접속 대기 큐 설정 성공\n");
}
// accept
struct sockaddr_in cli_addr;
size = sizeof(cli_addr);
printf("수신 대기 중...\n");
SOCKET cs = accept(s,(sockaddr*)&cli_addr,&size);
if(cs==INVALID_SOCKET){
printf("접속 승인 실패, 에러코드 = %u\n",WSAGetLastError());
// 소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("접속 승인 성공\n");
}
printf("클라이언트 접속 ! \n클라이언트 IP : %s, 포트 : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));
// getpeername
if( getpeername(s, (LPSOCKADDR)&cli_addr, &size) == SOCKET_ERROR){
printf("클라이언트 정보 얻기 실패, 에러코드 = %u\n",WSAGetLastError());
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("클라이언트 정보 얻기 성공\n");
}
printf("클라이언트 IP : %s, 포트 : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));
// select
FD_SET fd = {1,cs};
// 타임아웃 3초 {3,0}
TIMEVAL tv = {3,0};
int ret;
ret = select(0,&fd,NULL,NULL,&tv);
if(ret == 0){
printf("3초 동안 버퍼에 수신된 패킷이 없습니다.\n");
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}
if(ret == SOCKET_ERROR){
printf("소켓 통신 오류 발생, 에러코드 = %u\n",WSAGetLastError());
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}
// recv
char buf[10] = {0,};
int len = 5;
ret = recv(cs,buf,len,0);
if(ret == SOCKET_ERROR){
printf("소켓 통신 오류 발생, 에러코드 = %u\n",WSAGetLastError());
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}
printf("수신 데이터 = %s (%d bytes)\n",buf,ret);
// send
ret = recv(cs,buf,len,0);
if(ret == SOCKET_ERROR){
printf("데이터 송신 실패, 에러코드 = %u\n",WSAGetLastError());
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}
// shutdown
if(shutdown(cs, SD_BOTH) != 0){
printf("안전 종료 실패, 에러코드 = %u\n",WSAGetLastError());
// 클라이언트 접속 소켓 제거
closesocket(cs);
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("안전 종료 성공\n");
}
// closesocket
if(closesocket(cs) != 0){
printf("소켓 제거 실패, 에러코드 = %u\n",WSAGetLastError());
// 대기소켓제거
closesocket(s);
WSACleanup();
return false;
}else{
printf("소켓 제거 성공\n");
}
if(closesocket(s) != 0){
printf("소켓 제거 실패, 에러코드 = %u\n",WSAGetLastError());
WSACleanup();
return false;
}else{
printf("소켓 제거 성공\n");
}
// WSACleanup
if(WSACleanup() != 0){
printf("WSACleanup 실패, 에러코드 = %u\n",WSAGetLastError());
return false;
}else{
printf("WSACleanup 성공\n");
}
return true;
}
13. 6. 13.
C++(Windows) TCP 서버
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기