티스토리 뷰
책 ) 뇌를 자극하는 TCP/IP 소켓 프로그래밍
코드는 두가지로 Server 코드와 Client 코드 두개로 나뉘어집니다.
책을 공부하면서 원래는 기본적인 Socket 통신은 알고 있었지만, 구조체를 통해서도 데이터를 전달할 수 있다는 것을 알게 되었습니다.
따라서 소켓 프로그래밍을 할때 어떤 방식으로 구조체 데이터를 넘기는지 확인하시면 될 것 같습니다.
// DoummyClient
#pragma warning(disable:4996)
#include<stdio.h>
#include<iostream>
#include<Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 3600
#define IP "127.0.0.1"
void HandleError(const char* cause) {
int errCode = ::WSAGetLastError();
std::cout << cause << "Error Code : " << errCode << std::endl;
}
struct cal_data { //전달할 구조체
int left_num;
int right_num;
char op;
int result;
short int error;
};
int main() {
SOCKADDR_IN addr;
SOCKET s;
WSADATA wsaData;
char buffer[256];
int len;
int sbyte, rbyte;
struct cal_data sdata;
ZeroMemory((void*)&sdata, sizeof(sdata));
sdata.left_num = 100;
sdata.right_num = 50;
sdata.op = '+';
if (::WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
HandleError("WSAStartup");
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
HandleError("socket");
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr(IP);
addr.sin_port = ::htons(PORT);
if (::connect(s, (const sockaddr*)&addr, sizeof(addr)) == INVALID_SOCKET)
HandleError("connet");
len = sizeof(sdata);
sdata.left_num = htonl(sdata.left_num); //넘겨줄 데이터 저장 시
sdata.right_num = htonl(sdata.right_num); //네트워크 바이트 주소로 변경
sbyte = ::send(s, (char*)&sdata, len, 0); //char* 형태로 형변환 후 전달
if (sbyte != len)
HandleError("Send");
rbyte = recv(s, (char*)&sdata, len, 0); //데이터 전달 받음
if (rbyte != len)
HandleError("Recv");
if (ntohs(sdata.error != 0)) //네트워크 바이트를 호스트 바이트형식으로 변경
printf("CALC Error %d\n", ntohs(sdata.error));
printf("%d %c %d = %d \n", ntohl(sdata.left_num), // 출력
ntohl(sdata.op), ntohl(sdata.right_num), ntohl(sdata.result));
::closesocket(s);
WSACleanup();
}
//DummyServer
#pragma warning(disable:4996)
#include<stdio.h>
#include<iostream>
#include<Winsock2.h>
#include<string.h>
#include<io.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 3600
void HandleError(const char* cause) {
int errCode = ::WSAGetLastError();
std::cout << cause << "Error Code : " << errCode << std::endl;
}
struct cal_data {
int left_num;
int right_num;
char op;
int result;
short int error;
};
int main()
{
WSADATA wsaData;
SOCKET listen_s, client_s;
SOCKADDR_IN sock_addr, client_addr;
int addr_len;
int left_num, right_num;
short int cal_result;
struct cal_data rdata;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
HandleError("WSAStartup");
listen_s = socket(AF_INET, SOCK_STREAM, 0);
if (listen_s == INVALID_SOCKET)
HandleError("socket");
ZeroMemory(&sock_addr, sizeof(struct sockaddr_in));
sock_addr.sin_family = PF_INET;
sock_addr.sin_port = htons(PORT);
sock_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (bind(listen_s, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
HandleError("Bind");
return 1;
}
if (listen(listen_s, 5) == SOCKET_ERROR)
{
HandleError("listen");
return 1;
}
ZeroMemory(&client_addr, sizeof(struct sockaddr_in));
int nAcceptClientInfo = sizeof(struct sockaddr_in);
client_s = accept(listen_s, (struct sockaddr*)&client_addr, &nAcceptClientInfo);
int nReceiveBytes = 0;
printf("New Client Connected : %s\n", inet_ntoa(client_addr.sin_addr));
while (1)
{
recv(client_s, (char*)&rdata, sizeof(rdata), 0);
rdata.error = 0;
left_num = ntohl(rdata.left_num);
right_num = ntohl(rdata.right_num);
switch (rdata.op) {
case '+':
cal_result = left_num + right_num;
break;
case '-':
cal_result = left_num - right_num;
break;
case '*':
cal_result = left_num * right_num;
break;
case '/':
cal_result = left_num / right_num;
break;
default:
rdata.error = 1;
}
std::cout << "cal_result : " << cal_result << std::endl;
rdata.result = htonl(cal_result);
rdata.error = htonl(cal_result);
send(client_s, (char*)&rdata, sizeof(rdata), 0);
break;
}
closesocket(listen_s);
WSACleanup();
return 0;
}
'서버 공부 > 네트워크' 카테고리의 다른 글
소켓 네트워크 프로그래밍) 데이터 전송 방식 -> 가변 길이 데이터 전송 (0) | 2022.07.04 |
---|---|
소켓 네트워크 프로그래밍) 세마포어 멀티쓰레드 (0) | 2022.07.02 |
소켓 네트워크 프로그래밍) UDP 소켓 기본 통신 (0) | 2022.07.01 |
소켓 네트워크 프로그래밍) IP 클래스 확인 (0) | 2022.06.29 |
소켓 네트워크 프로그래밍) 파일 카피 (0) | 2022.06.29 |
댓글