🧼C, C++/네트워크

소켓 커스텀 송수신함수 구현 C++

Mawile 2020. 11. 26.
728x90

안녕하세요~!

이번에는 소켓 송수신 함수를 좀 더 안정적으로 만들었습니다

 

 

 

예를 들어서

클라이언트 측에서 "Hello world"라는 문구를 서버로 전송했다고 칩시다.

이때의 데이터의 길이는 11, 데이터의 크기는 12가 될 겁니다.

 

만약 strlen() 즉, 문자열의 길이를 전송했을 경우,서버 측에서는 이것을 11만큼 받아야 합니다.

아니면 sizeof() 즉, 문자열의 크기를 전송했을 경우, 서버 측에서는 이것을 12만큼 받아야 합니다.

 

만약 클라이언트 측에서 데이터의 양을 20을 보냈는데 서버측에서 데이터의양을 10을 받으면,

소켓 버퍼에는 10만큼의 데이터가 남게 돼서 그 코드에는 오류는 발생하지 않지만, 결함이 발생하게 됩니다.

 

그리고 서버 측에서는 클라이언트 측에서 보내는 데이터의 크기나 길이를 모릅니다.

그래서 이것을 편의성 있고 결함을 제외시키기 위한 커스텀 함수를 만들었습니다~!

 

 

 

 

 

이야기가 좀 딱딱했네요...ㅋㅋ.....

 

 

 

 

728x90

 

 

 


 

[[[   소스코드(서버:송신)   ]]]

#include <winsock2.h>
#include <iostream>

using namespace std;

int dp_send(SOCKET s,const char *str){ //커스텀 송신함수
	char bf[100]={0};
	int size=0;
	while(str[size]!='\0') size++; //사이즈계산
	itoa(size,bf,10); //int->char형변환
	send(s,bf,100,0); //크기송신
	//SetConsoleTitle(bf); //정상적으로 잘되었는지 확인용함수
	int ret = send(s,str,size,0); //데이터송신
	return ret;
}

int dp_recv(SOCKET s,char *str){ //커스텀 수신함수
	char bf[100]={0};
	recv(s,bf,100,0); //크기수신
	int size = atoi(bf); //char->int형변환
	//SetConsoleTitle(bf); //정상적으로 잘되었는지 확인용함수
	int ret = recv(s,str,size,0); //데이터수신
	return ret;
}

void StrToChr(string str,char *chr){ //string->char형변환 함수
	int cnt=0,i;
	while(str[cnt]!='\0') cnt++;
	for(i=0;i<sizeof(chr);i++) chr[i]='\0';
	for(i=0;i<cnt;i++) chr[i]=str[i];
}

int main(){
	WSADATA wsa;
	WSAStartup(MAKEWORD(2,2), &wsa);
	
	SOCKET server=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	
	SOCKADDR_IN addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8080);
	addr.sin_addr.s_addr=htonl(INADDR_ANY);
	
	bind(server,(SOCKADDR*)&addr,sizeof(addr));
	listen(server,SOMAXCONN);
	
	SOCKADDR_IN client_sock={0};
	int client_size = sizeof(client_sock);
	SOCKET client = accept(server,(SOCKADDR*)&client_sock,&client_size);

	const int len=512;
	char buf[len]={0};
	string str;
	
	while(1){
		getline(cin,str); //cin으로안하는이유: 띄어쓰기포함
		StrToChr(str,buf); //형변환
		dp_send(client,buf); //커스텀송신
	}
}

 

 

 

 

[[[   소스코드(클라이언트:수신)   ]]]

#include <winsock2.h>
#include <iostream>

using namespace std;

int dp_send(SOCKET s,const char *str){ //(서버와같습니다)
	char bf[100]={0};
	int size=0;
	while(str[size]!='\0') size++;
	itoa(size,bf,10);
	send(s,bf,100,0);
	//SetConsoleTitle(bf);
	int ret = send(s,str,size,0);
	return ret;
}

int dp_recv(SOCKET s,char *str){ //(서버와같습니다)
	char bf[100]={0};
	recv(s,bf,100,0);
	int size = atoi(bf);
	//SetConsoleTitle(bf);
	int ret = recv(s,str,size,0);
	return ret;
}

int main(){
	WSADATA wsa;
	WSAStartup(MAKEWORD(2,2), &wsa);
	
	SOCKET server=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	
	SOCKADDR_IN addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8080);
	addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //127.0.0.1 -> localhost
	
	while(connect(server,(SOCKADDR*)&addr,sizeof(addr)));
	
	const int len=512;
	char buf[len]={0};
	while(1){
		ZeroMemory(buf,len); //메모리비우기 = memset(buf,0,len);과같습니다
		dp_recv(server,buf); //커스텀수신
		if(!WSAGetLastError()) cout << buf << endl; //만약 서버가 안닫혔을때에만 메세지출력
	}
}

 

 

 

 

 

 

"hello world~~"의 데이터의 길이인 13이 제목으로 잘 보이네요~!

 

 

 


 

 

그리고 이해가 가지 않는 부분이

있다면 댓글로 질문 주세요!

그럼,

 

감사합니다~!

 

 

 

 

구글검색 키워드

c언어 C언어 c++ C++ 소켓 강좌 커스텀 함수

728x90

'🧼C, C++ > 네트워크' 카테고리의 다른 글

다중 클라이언트 C++ TCP #3 (수정본)  (2) 2020.12.24
소켓 파일전송 C++ #2  (0) 2020.11.26
다중 클라이언트 C++ TCP #3  (1) 2020.11.09
다중 클라이언트 C++ TCP #2  (2) 2020.11.05
소켓 버퍼 비우기 C++  (0) 2020.10.17

댓글