소개 코드를 머리 속에서 최대한 외울려고 했는데, 서버에서 bind 부분이랑 accept 이 막혔습니다. 기존에 준 ref 코드와 다른 것은 오류를 최대한 막을려고 했기 때문에 ref 기반에서 출발했지만 약간 다릅니다. 하지만 거의 같습니다. 제가 했던 리포트랑 엄청 짧고 간편해졌습니다;
/*
tcp_server_ref.cpp
저작권
http://ccl.korea.ac.kr
http://cakel.tistory.com
교육용을 전제로 자유롭게 사용하실수 있습니다.
5000 번 포트를 쓰는 로컬호스트용 애코 서버 입니다.
되도록이면 머리 속에서 나오는 것을 쳐 낼려고 했습니다.
*/
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#pragma comment (lib,"ws2_32.lib")
#define PORT 5000
int main()
{
// 윈속 초기화
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("winsock 오류\n");
return 1;
}
// 서버 주소, 받을 클라이언트 주소
int s, ns, addrsize;
sockaddr_in client, server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 로컬 서버(localhost)를 나타냄. 혼자 놀이용.
server.sin_port = htons(PORT);
// bind() - 새로 오는 클라이언트를 받을 welcome 소켓
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(bind(s, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("bind() 오류\n");
WSACleanup();
return 1;
}
// listen 포트를 열어 두어 떡밥을 기다리는 중
listen(s,2);
printf("클라이언트를 기다리는 중\n");
addrsize = sizeof(client);
char buff[1024] = {0};
// accept 물었다. 소켓을 할당 한다.
ns = accept(s, (sockaddr*)&client, &addrsize);
if(ns == INVALID_SOCKET)
{
printf("accept() 오류\n");
WSACleanup();
return 1;
}
// inet_ntoa 랑 ntohs 를 주의
printf("%s:%d로 접속\n", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
int ret;
// 값을 주고 받는데 메시지 값이 SOCKET_ERROR 이면 가차없이 종료
while(ret != SOCKET_ERROR)
{
ret = recv(ns, buff, 1024, 0);
printf("받은 메시지의 크기 : %d\n", ret);
if(ret == SOCKET_ERROR) break;
ret = send(ns, buff, ret, 0);
printf("보낸 메시지의 내용 : %s\n", buff);
memset(buff, 0, 1024);
}
printf("접속을 종료\n");
closesocket(ns);
closesocket(s);
WSACleanup();
return 0;
}
/*
tcp_client_ref.cpp
저작권
http://ccl.korea.ac.kr
http://cakel.tistory.com
교육용을 전제로 자유롭게 사용하실수 있습니다.
5000 번 포트를 쓰는 로컬호스트용 애코 클라이언트 입니다.
되도록이면 머리 속에서 나오는 것을 쳐 낼려고 했습니다.
*/
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#pragma comment (lib,"ws2_32.lib")
#define PORT 5000
#define IP "127.0.0.1" // 로컬 접속용 즉 혼자놀이용
int main(void)
{
// 윈속을 설정
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
fprintf(stderr,"틀린 윈속 버전\n");
return 1;
}
int s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( s == SOCKET_ERROR)
{
fprintf(stderr,"socket() 함수 오류\n");
WSACleanup();
return 1;
}
// 서버 주소 설정
sockaddr_in server;
server.sin_addr.s_addr = inet_addr(IP);
server.sin_port = htons(PORT);
server.sin_family = AF_INET;
// connect() 떡밥을 물으러 간다.
if(connect(s, (sockaddr* )&server, sizeof(server)) == SOCKET_ERROR)
{
printf("connect() 오류\n");
closesocket(s);
WSACleanup();
return 1;
}
// 물었다.
char buff[1024] = {0};
int ret;
// SOCKET_ERROR 되기 전까진 무조건 자료 전송
while(ret != SOCKET_ERROR)
{
printf("출력할 글자 입력 : ");
fgets(buff,1024,stdin);
ret = send(s, buff, strlen(buff),0);
memset(buff,0,1024);
if(ret == 0) break;
ret = recv(s, buff, 1024,0);
printf("받은 문자열 : %s", buff);
}
printf("연결을 종료\n");
closesocket(s);
WSACleanup();
return 0;
}