본문 바로가기
코스웨어/15년 스마트컨트롤러

2015-11-30 Win32 API Socket 개인업무일지 - 천정호

by 알 수 없는 사용자 2015. 12. 1.
728x90
반응형

Unix와 Win32의 Socket 프로그램은 비슷하다.


초기 넣어줘야하는 부분

#pragma comment(lib, "Ws2_32.lib")


 if(WSAStartup(MAKEWORD(2,2),&wsaData)!= 0) 
    { 
        printf("error\r\n"); 
        return 0; 
    } 


	WSACleanup();
	return 0;



--- Server.c ---

#include <stdio.h>

#include <string.h>

#include <Winsock2.h>


// Visual Studio에서 컴파일을 하면 Lib 파일을 자동으로 추가해준다.

// CMD나 GCC에서는 Lib를 사용하기 위해서 Ws2_32.lib를 추가해야한다.

// Winsock.h <-> wsock32.lib Winsock2.h <-> Ws2_32.lib

#pragma comment(lib, "Ws2_32.lib")


#define PORT 7777

#define IP 192.168.0.0

#define MAX_PACKETLEN 512 


int main() {

WSADATA WsaData;

SOCKET S_Sock, C_Sock;

// struct sockaddr_in == SOCKADDR_IN

SOCKADDR_IN S_Addr;


int Status;

int iSock_Len;


char ReadBuffer[MAX_PACKETLEN];


// WinSock을 사용하겠다고 알린다.

// 첫 번째 인자는 Windows Socket의 버전을 선택한다.

if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0) {

printf("Window Socket API Start Error.\n");

return 1;

}

S_Sock = socket(AF_INET, SOCK_STREAM, 0);

if (S_Sock == INVALID_SOCKET) {

printf("Socket Error.\n");

return 1;

}


printf("Success Socket Create.\n");

memset(&S_Addr, 0, sizeof(SOCKADDR_IN));


S_Addr.sin_family = AF_INET;

S_Addr.sin_port = htons(PORT);

// INADDR_ANY 사용시에는 자기 자신의 IP로 자동 설정된다.

// 수동으로 IP를 설정하고 싶으면 인자로 IP를 넣어주면 된다.

S_Addr.sin_addr.S_un.S_addr = inet_addr("10.211.55.19");


Status = bind(S_Sock, (SOCKADDR *)&S_Addr, sizeof(SOCKADDR_IN));

if (Status == SOCKET_ERROR) {

printf("Bind Error.\n");

return 1;

}


if (SOCKET_ERROR == listen(S_Sock, 5)) {

printf("Listen Error.\n");

return 1;

}


while (1) {

memset(&S_Addr, 0, sizeof(SOCKADDR_IN));


// Socket의 길이 추출

iSock_Len = sizeof(SOCKADDR_IN);


// 현재 S_Addr은 접속하는 사용자의 정보를 가지는 역활을 한다.

C_Sock = accept(S_Sock, (SOCKADDR *)&S_Addr, &iSock_Len);

if (C_Sock == INVALID_SOCKET)

{

printf("Accept Error.\n");

closesocket(S_Sock);

WSACleanup();

return 1;

}


// 접속자 정보 출력

printf("Incomming Client [%s] : [%d]\n", inet_ntoa(S_Addr.sin_addr), ntohs(S_Addr.sin_port));


iSock_Len = recv(C_Sock, ReadBuffer, MAX_PACKETLEN, 0);


if (iSock_Len > 0)

{

iSock_Len = send(C_Sock, ReadBuffer, iSock_Len, 0);

}

else

{

printf("read Error\n");

}

closesocket(C_Sock);


if (strcmp(ReadBuffer, "Quit\n") == 0) {

break;

}

}


// Socket Close

closesocket(S_Sock);

WSACleanup();


return 0;

}





--- Client.c ---

#include <stdio.h>

#include <string.h>

#include <Winsock2.h>


// Visual Studio에서 컴파일을 하면 Lib 파일을 자동으로 추가해준다.

// CMD나 GCC에서는 Lib를 사용하기 위해서 Ws2_32.lib를 추가해야한다.

// Winsock.h <-> wsock32.lib Winsock2.h <-> Ws2_32.lib

#pragma comment(lib, "Ws2_32.lib")


#define PORT 7777

#define IP 192.168.0.0

#define MAX_PACKETLEN 1024 


int main(int argc, char *argv[]) {

WSADATA WsaData;

SOCKET C_Sock;

// struct sockaddr_in == SOCKADDR_IN

SOCKADDR_IN S_Addr;


int iSock_Len;


char ReadBuffer[MAX_PACKETLEN];


if (argc != 2) {

printf("Usage : [%s] [IP Address]\n", argv[0]);

return 1;

}


// WinSock을 사용하겠다고 알린다.

// 첫 번째 인자는 Windows Socket의 버전을 선택한다.

if (WSAStartup(MAKEWORD(2, 2), &WsaData) != NO_ERROR) {

printf("Window Socket API Start Error.\n");

return 1;

}


C_Sock = socket(AF_INET, SOCK_STREAM, 0);

if (C_Sock == INVALID_SOCKET) {

printf("Socket Error.\n");

return 1;

}


printf("Success Socket Create.\n");

memset(&S_Addr, 0, sizeof(SOCKADDR_IN));


S_Addr.sin_family = AF_INET;

S_Addr.sin_port = htons(PORT);

S_Addr.sin_addr.S_un.S_addr = inet_addr(argv[1]);


if (connect(C_Sock, (SOCKADDR *)&S_Addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {

printf("Connect Error.\n");

return 1;

}


while (1) {

printf("> ");

fgets(ReadBuffer, MAX_PACKETLEN - 1, stdin);

if (strcmp(ReadBuffer, "Quit\n") == 0) {

break;

}

send(C_Sock, (void *)ReadBuffer, strlen(ReadBuffer), 0);

recv(C_Sock, (void *)ReadBuffer, MAX_PACKETLEN, 0);

printf("Server -> %s\n", ReadBuffer);

}


// Socket Close

closesocket(C_Sock);

WSACleanup();


return 0;

}

728x90