무슨 일로 C 하셨습니까?

[C] 소켓 프로그래밍::FTP - 연결 본문

C - 이걸 굳이?/FTP

[C] 소켓 프로그래밍::FTP - 연결

OJJJ 2020. 12. 4. 20:21

소켓 프로그래밍을 통해 서버-클라이언트를 만들어보겠다.


서버와 클라이언트의 기본적인 TCP연결 및 메시지 보내기는

 

조금만 검색해보아도 금방 나오고, 내용 또한 금방 이해를 할 수 있다.

void server() {
	WSADATA wsa;
	WSAStartup(0x0202, &wsa);
	
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

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

	serv.sin_addr.S_un.S_addr = INADDR_ANY;
	serv.sin_family = AF_INET;
	serv.sin_port = htons(9000);

	int serv_sz = sizeof(serv);
	if (bind(sock, (SOCKADDR*) & serv, serv_sz) != 0) {
		printf("binding error\n");
	}

	if (listen(sock, 10) !=0) {
		printf("listen error\n");
	}

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

	int clnt_sz = sizeof(clnt);
	SOCKET clnt_sock = accept(sock, (SOCKADDR*) & clnt, &clnt_sz);

	char msg[100];
	recv(clnt_sock, msg, 100, 0);
	
	printf("msg is : %s\n", msg);
}
void client() {

	WSADATA wsa;
	WSAStartup(0x0202, &wsa);

	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

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

	serv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	serv.sin_family = AF_INET;
	serv.sin_port = htons(9000);

	int serv_sz = sizeof(serv);
	if (connect(sock, (SOCKADDR*) & serv, serv_sz) != 0) {
		puts("Connect error!");
	}

	send(sock, "hi", StringLength("hi") /* strlen("hi") */, 0);
}

그래서 기본적인 코드를 긁어 모아서 아주 기본적인 연결 코드를 만들었다.

 

각각 서버와 클라이언트이다.

 

#include<WinSock2.h>
#include"StringFunc.h"

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

헤더는 다음과 같이 추가해주면 된다.

 


그런데 가만보면 서버나 클라이언트나 겹치는 부분이 존재한다.

 

따라서 함수로 묶어 버리도록 하겠다.

struct sockaddr_in AdrInit(char* ip, int port) {
	SOCKADDR_IN adr;

	memset(&adr, 0, sizeof(adr));

	adr.sin_addr.S_un.S_addr = inet_addr(ip);
	adr.sin_family = AF_INET;
	adr.sin_port = htons(port);

	return adr;
}

서버 클라이언트 간 연결에 사용될 주소 구조체의 초기화 함수

 

SOCKET open(SOCKET sock, SOCKADDR_IN adr) {
	int adr_sz = sizeof(adr);
	if (bind(sock, (SOCKADDR*)&adr, adr_sz) != 0) {
		printf("binding error\n");
		return -1;
	}

	if (listen(sock, 10) != 0) {
		printf("listen error\n");
		return -1;
	}

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

	int clnt_sz = sizeof(clnt);
	SOCKET clnt_sock = accept(sock, (SOCKADDR*)&clnt, &clnt_sz);

	return clnt_sock;
	
}

서버 입장에서 바인딩부터 연결승인까지 묶은 함수

 

이렇게 두 함수로 연결에 관련된 코드를 간단하게 만들겠다.

 

그리고 서버와 클라이언트의 연결부분을 함수로 하여

// 수신자(클라이언트) 연결함수
SOCKET Receiver_Connector() {

	WSADATA wsa;
	WSAStartup(0x0202, &wsa);

	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	SOCKADDR_IN serv = AdrInit("127.0.0.1", 9000);

	if (connect(sock, (SOCKADDR*)&serv, sizeof(serv)) != 0) puts("Connect error!");

	return sock;
}
// 송신자(서버) 연결함수
SOCKET Sender_Connector() {
	WSADATA wsa;
	WSAStartup(0x0202, &wsa);
	
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	SOCKADDR_IN adr = AdrInit("0.0.0.0", 9000);
	
	SOCKET clnt_sock = Ready(sock, adr);

	return clnt_sock;
}

이번 프로젝트에 맞게 서버(송신자), 클라이언트(수신자)로 이름을 바꿔 연결 함수로 만들면 되겠다.

 

각 측에서 함수를 통해 생성된 SOCKET을 반환받아서 사용하면 되겠다.

 

 

Comments