티스토리 뷰
책 ) 뇌를 자극하는 TCP/IP 소켓 프로그래밍
TCP 와는 달리 Clinet 측에서는 Connect가 할 필요가 없고, Server쪽에서는 Listen, Accept를 할 필요가 없다.
왜냐하면 UDP는 데이터를 그냥 보내기 때문이다.
#DummyClient(UDP)
#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"
#define MAXLEN 256
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 msg[MAXLEN];
int sbyte, rbyte;
int left_num, right_num;
int addrlen;
char op = NULL;
struct cal_data sdata;
ZeroMemory((void*)&sdata, sizeof(sdata));
if (::WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
HandleError("WSAStartup");
s = socket(AF_INET, SOCK_DGRAM, 0);
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);
while (1) {
printf("> ");
fgets(msg, MAXLEN - 1, stdin);
if (strncmp(msg, "quit\n", 5) == 0)
break;
sscanf(msg, "%d %c %d", &left_num, &op, &right_num);
memset((void*)&sdata, 0x00, sizeof(sdata));
sdata.left_num = htonl(left_num);
sdata.right_num = htonl(right_num);
sdata.op = op;
addrlen = sizeof(addr);
sbyte = ::sendto(s, (char*)&sdata, sizeof(sdata), 0, (struct sockaddr*)&addr, addrlen);
rbyte = recvfrom(s, (char*)&sdata, sizeof(sdata), 0, (struct sockaddr*)&addr, &addrlen);
printf("%d %c %d = %d \n", ntohl(sdata.left_num),
sdata.op, ntohl(sdata.right_num), ntohl(sdata.result));
}
::closesocket(s);
WSACleanup();
}
#DummyServer(UDP)
#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 sockfd;
SOCKADDR_IN sock_addr, client_addr;
int addr_len;
int left_num, right_num;
short int cal_result = 0;
struct cal_data rdata;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
HandleError("WSAStartup");
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
HandleError("socket");
ZeroMemory(&sock_addr, sizeof(struct sockaddr_in));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(PORT);
sock_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr_len = sizeof(sock_addr);
if (bind(sockfd, (struct sockaddr*)&sock_addr, addr_len) == SOCKET_ERROR)
{
HandleError("Bind");
return 1;
}
while (1)
{
addr_len = sizeof(client_addr);
recvfrom(sockfd, (char*)&rdata, sizeof(rdata), 0, (struct sockaddr *)&client_addr, &addr_len);
#if DEBUG
printf("Client Info : %s (%d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
printf("%d %c %d\n", ntohl(rdata.left_num), rdata.op, ntohl(rdata.right_num));
#endif // DEBUG
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);
sendto(sockfd, (char*)&rdata, sizeof(rdata), 0,(struct sockaddr*)&client_addr, addr_len);
}
closesocket(sockfd);
WSACleanup();
return 0;
}
'서버 공부 > 네트워크' 카테고리의 다른 글
소켓 네트워크 프로그래밍) 데이터 전송 방식 -> 가변 길이 데이터 전송 (0) | 2022.07.04 |
---|---|
소켓 네트워크 프로그래밍) 세마포어 멀티쓰레드 (0) | 2022.07.02 |
소켓 네트워크 프로그래밍) TCP/IP 구조체 데이터 전달 (0) | 2022.06.30 |
소켓 네트워크 프로그래밍) IP 클래스 확인 (0) | 2022.06.29 |
소켓 네트워크 프로그래밍) 파일 카피 (0) | 2022.06.29 |
댓글