예제를 작성하기 전에 TCP/IP 프로그래밍을 하기 위해서는 winsock2.h 헤더파일이 포함되어야 합니다.
이를 위해서는 ws2_32.lib 라이브러리를 링크시켜야 합니다.
(프로젝트 '속성'->'구성 속성'->'입력'->'추가 종속성'->ws2_32.lib 추가)
이를 마치고 나면 프로그램을 작성하고 실행하시면 되는데 우선 서버 프로그램 예제부터 실행하시고 클라이언트 예제를 실행하셔야 정상적으로 작동합니다.
<서버 프로그램>
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
void ErrorHandling(char *message);
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAddr, clntAddr;
int szClntAddr;
char message[] = "Hello World!";
if (argc != 2)
{
printf("Usage:%s <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //소켓 라이브러리 초기화
ErrorHandling("WSAStartup() error!");
hServSock = socket(PF_INET, SOCK_STREAM, 0); //소켓생성
if (hServSock == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
if (bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) //소켓에 IP주소와 PORT 번호 할당
ErrorHandling("bind() error");
if (listen(hServSock, 5) == SOCKET_ERROR) //listen 함수호출을 통해서 생성한 소켓을 서버 소켓으로 완성
ErrorHandling("listen() error");
szClntAddr = sizeof(clntAddr);
hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr); //클라이언트 연결요청 수락하기 위해 accept함수 호출
if (hClntSock == INVALID_SOCKET)
ErrorHandling("accept() error");
send(hClntSock, message, sizeof(message), 0); //send함수 호출을 통해서 연결된 클라이언트에 데이터를 전송
closesocket(hClntSock);
closesocket(hServSock);
WSACleanup(); //프로그램 종료 전에 초기화한 소켓 라이브러리 해제
return 0;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
정상적으로 실행이 된다면 위와 같이 cmd창이 멈추고 커서가 깜빡이기만 할 것입니다.
<클라이언트 예제>
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
void ErrorHandling(char *message);
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char message[30];
int strLen;
if (argc != 3)
{
printf("Usage:%s <IP> <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //소켓 라이브러리를 초기화하고 있다
ErrorHandling("WSAStartup() error!");
hSocket = socket(PF_INET, SOCK_STREAM, 0); //소켓을 생성하고
if (hSocket == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) //생성된 소켓을 바탕으로 서버에 연결요청을 하고 있다
ErrorHandling("connect() error!");
strLen = recv(hSocket, message, sizeof(message) - 1, 0); //recv 함수 호출을 통해서 서버로부터 전송되는 데이터를 수신하고 있다.
if (strLen == -1)
ErrorHandling("read() error");
printf("Message from server:%s\n", message);
closesocket(hSocket); //소켓 라이브러리 해제
WSACleanup();
return 0;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
정상적으로 작동이 된다면 이렇게 서버로부터 Hello World!라는 메세지를 받으실 수 있을 것입니다.
(127.0.0.1은 자신의 PC를 가리키는 주소입니다)
한 컴퓨터에서 서버프로그램과 클라이언트 프로그램을 동시에 실행하기 위해서는 비쥬얼 스튜디오 2개를 켜서 프로그램을 돌리시면 됩니다!
(주의 하실점은 서버, 클라이언트 프로그램을 각각 다른 프로젝트에 실행시켜야합니다. )
* 2022.10.10 업데이트
클라이언트 파일이 정상적으로 컴파일 되지 않으실 경우 아래 코드를 상단에 추가해주세요.
#define _WINSOCK_DEPRECATED_NO_WARNINGS
[참고]:윤성우 저 TCP/IP 소켓 프로그래밍
'C > TCPIP 소켓 프로그래밍(윤성우 저)' 카테고리의 다른 글
TCP/IP 소켓 프로그래밍 4장 내용 확인문제 (0) | 2017.05.22 |
---|---|
TCP/IP 소켓 프로그래밍 3장 내용 확인문제 (0) | 2017.05.18 |
TCP/IP 소켓 프로그래밍 2장 내용 확인문제 (0) | 2017.05.16 |
TCP/IP 소켓 프로그래밍 1장 내용확인 문제 (0) | 2017.05.13 |
리눅스 기반 서버, 클라이언트 예제 (5) | 2017.05.13 |