소켓 통신을 하기위하여 기본적인 라이브러리 추가 방법을 모른다면 이전 글을 참조해주세요
위 이미지처럼 결과가 나오게끔 코드를 공개하겠습니다.
클라이언트 코드
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 512
int main(int argc, char* argv[]) {
int retval;
// 윈속 초기화
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return -1;
// socket()
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return -1;
printf("UDP 소켓이 생성되었습니다.\n");
// 소켓 주소 구조체 초기화
SOCKADDR_IN serveraddr;
ZeroMemory(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 데이터 통신에 사용할 변수
SOCKADDR_IN peeraddr;
int addrlen;
char buf[BUFSIZE + 1];
int len;
for (int i = 0; i < 5; i++) {
// 데이터 입력
printf("\n[보낼 데이터]");
fgets(buf, BUFSIZE + 1, stdin); // buf 에 BUFSIZE +1 만큼의 크기를 입력 buf는 배열의 시작 주소를 가르킨다.
// 배열의 이름 = 배열의 시작 주소
//stdin -> 키보드 입력 사용
// '\n' 문자 제거
len = strlen(buf);
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
// printf("buf: %s\n", buf);
// 데이터 보내기
retval = sendto(sock, buf, strlen(buf), 0, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
if (retval == SOCKET_ERROR) return -1;
printf("[클라이언트] %d바이트를 보냈습니다.\n", retval);
// 데이터 받기
addrlen = sizeof(peeraddr);
retval = recvfrom(sock, buf, BUFSIZE, 0,
(SOCKADDR*)&peeraddr, &addrlen);
printf("서버로 부터 데이터를 받았습니다. \n\n");
// 송신자의 IP 주소 체크
if (memcmp(&peeraddr, &serveraddr, sizeof(peeraddr)))
{
printf("[오류] 잘못된 데이터 입니다!\n");
return -1;
}
//받은 데이터 출력
buf[retval] = '\0';
printf("[클라이언트] %d바이트를 받았습니다.\n", retval);
printf("[받은 데이터] %s\n", buf);
}
// closesocket()
closesocket(sock);
// 윈속 종료
WSACleanup();
return 0;
}
서버 코드
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 512
int main(int argc, char* argv[])
{
int retval;
// 윈속 초기화
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return -1;
// socket()
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return -1;
printf("UDP 소켓이 생성되었습니다.\n");
// bind()
SOCKADDR_IN serveraddr;
ZeroMemory(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000); // host(컴퓨터가 데이터 읽는 방식) 방식을 network방식으로 변경
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
if (retval == SOCKET_ERROR) return -1;
printf("Bind 완료 되었습니다.\n");
//데이터 통신에 사용할 변수
SOCKADDR_IN clientaddr;
int addrlen;
char buf[BUFSIZE + 1];
for (int i = 0; i < 5; i++) {
// 데이터 받기
addrlen = sizeof(clientaddr);
retval = recvfrom(sock, buf, BUFSIZE, 0,
(SOCKADDR*)&clientaddr, &addrlen);
printf("Client로 부터 데이터를 받았습니다.\n");
// 받은 데이터 출력
buf[retval] = '\0';
printf("[UDP/%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr),
ntohs(clientaddr.sin_port), buf);
// 데이터 보내기
retval = sendto(sock, buf, retval, 0,
(SOCKADDR*)&clientaddr, sizeof(clientaddr));
printf("Client로 데이터를 전송했습니다.");
}
// closesocket()
closesocket(sock);
// 윈속 종료
WSACleanup();
return 0;
}
'네트워크' 카테고리의 다른 글
ARP(Address Resolution Protocol - 주소 결정 프로토콜) (0) | 2020.08.29 |
---|---|
[c언어] 3바이트, 6바이트 데이터 타입 만들기 (0) | 2020.08.16 |
[c언어]8바이트를 위한 htonl (1) | 2020.08.16 |
윈도우에서 비주얼 스튜디오로 간단한 소켓통신 해보기 (0) | 2020.08.13 |
LTE 네트워크 구조 학습 #1 (0) | 2020.08.07 |