🧼C, C++/네트워크
소켓 구조체 정보 전송 C++ TCP
시작하기 앞서서 사용한 운영체제는 Windows10이며IDE는 DevCpp이고 사용한 언어는 C++11입니다!
안녕하세요!!
이번에는 간단명료하게 원리 설명과 소스코드 뿌리고 빠지겠습니다~!!(ㅋㅋㅋㅋ)
궁금한 부분이 있다면 모두 질문 주세요~!!!!!!!!!!!!!
[[ 참고자료 ]]
이번에도 역시 "소켓 기본 틀 #2"를 사용하였습니다!
[[ 서버#1 ]]
#include <iostream>
#include <winsock2.h>
using namespace std;
#define PACKET_SIZE 1024
typedef struct _type{
int das;
char test[PACKET_SIZE];
}type; //int형과 char*형을 저장한 구조체
int main(){
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0){
cout << "WSA error";
return 0;
}
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(skt==INVALID_SOCKET){
cout << "socket error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(4444);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(skt, (SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR){
cout << "bind error";
closesocket(skt);
WSACleanup();
return 0;
}
if(listen(skt,SOMAXCONN)==SOCKET_ERROR){
cout << "listen error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN client = {0};
int client_size = sizeof(client);
SOCKET client_sock;
client_sock = accept(skt,(SOCKADDR*)&client,&client_size);
if(client_sock==INVALID_SOCKET){
cout << "accept error";
closesocket(client_sock);
closesocket(skt);
WSACleanup();
return 0;
}
type tp;
char buf[PACKET_SIZE];
while(1){
cin >> buf;
tp.das = atoi(buf); //데이터저장
cin >> buf;
strcpy(tp.test,buf); //데이터저장
send(client_sock,(char*)&tp,PACKET_SIZE,0); //구조체 형변환
}
closesocket(client_sock);
closesocket(skt);
WSACleanup();
}
[[ 클라이언트#1 ]]
#include <iostream>
#include <winsock2.h>
#include <thread>
using namespace std;
#define PACKET_SIZE 1024
typedef struct _type{
int das;
char test[PACKET_SIZE];
}type;
type *tp; //구조체 전체로 정의
void reada(SOCKET &s){
char buf[PACKET_SIZE];
while(1){
recv(s,buf,PACKET_SIZE,0);
tp = (type*)buf; //형변환
}
}
int main(){
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
cout << "WSA error";
WSACleanup();
return 0;
}
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(skt==INVALID_SOCKET){
cout << "socket error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(4444);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
while(connect(skt, (SOCKADDR*)&addr,sizeof(addr)));
thread (reada,ref(skt)).detach();
char dasd[PACKET_SIZE];
while(1){
cin >> dasd;
cout << "int: " << tp->das << endl;
cout << "char*: " << tp->test << endl;
}
closesocket(skt);
WSACleanup();
}
int형과 char형을 순서대 로저 장하고 그 데이터를 클라이언트로 전송한 뒤,
클라이언트 측에서 멀티스레드로 계속 정보를 받아오면서
아무 키나 누를 시 그 구조체의 정보를 확인할 수 있게 했고요
정상 작동되네요!
일단 구조체 정보를 전송하는 거는 이렇게 하는데..
만약 구조체 배열을 전송하려면 어떻게 소스코드가 변할까요?
서버#2 ]]
#include <iostream>
#include <winsock2.h>
using namespace std;
#define PACKET_SIZE 1024
#define MAX 5
typedef struct _type{
int das;
char test[PACKET_SIZE];
}type;
int main(){
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0){
cout << "WSA error";
return 0;
}
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(skt==INVALID_SOCKET){
cout << "socket error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(4444);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(skt, (SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR){
cout << "bind error";
closesocket(skt);
WSACleanup();
return 0;
}
if(listen(skt,SOMAXCONN)==SOCKET_ERROR){
cout << "listen error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN client = {0};
int client_size = sizeof(client);
SOCKET client_sock;
client_sock = accept(skt,(SOCKADDR*)&client,&client_size);
if(client_sock==INVALID_SOCKET){
cout << "accept error";
closesocket(client_sock);
closesocket(skt);
WSACleanup();
return 0;
}
type *tp = new type[MAX]; //MAX만큼 동적할당
char buf[PACKET_SIZE];
while(1){
for(int i=0;i<MAX;i++){
cin >> (tp+i)->das >> (tp+i)->test; // 구조체내용 입력
}
for(int i=0;i<MAX;i++) send(client_sock,(char*)&tp[i],PACKET_SIZE,0);
//차례대로 구조체정보 보내기
}
closesocket(client_sock);
closesocket(skt);
WSACleanup();
delete[] tp;
}
[[ 클라이언트#2 ]]
#include <iostream>
#include <winsock2.h>
#include <thread>
using namespace std;
#define PACKET_SIZE 1024
#define MAX 5
typedef struct _type{
int das;
char test[PACKET_SIZE];
}type;
type *tp;
void reada(SOCKET &s){
char buf[PACKET_SIZE];
while(1){
for(int i=0;i<MAX;i++){
recv(s,buf,PACKET_SIZE,0); // 구조체정보 차례대로 받기
memcpy(&tp[i],buf,PACKET_SIZE); // 메모리복사
}
}
}
int main(){
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
cout << "WSA error";
WSACleanup();
return 0;
}
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(skt==INVALID_SOCKET){
cout << "socket error";
closesocket(skt);
WSACleanup();
return 0;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(4444);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
while(connect(skt, (SOCKADDR*)&addr,sizeof(addr)));
thread (reada,ref(skt)).detach();
char dasd[PACKET_SIZE];
int i;
tp = new type[MAX]; // MAX만큼 동적할당
while(1){
cin >> dasd;
for(i=0;i<MAX;i++){ //아무거나 입력시 내용출력
cout << "int: " << (tp+i)->das << endl;
cout << "char*: " << (tp+i)->test << endl;
cout << "\n\n";
}
}
closesocket(skt);
WSACleanup();
delete[] tp;
}
그리고 "(tp+i)->das"는 "tp [i]. das"와 같은 표현입니다!
송수신 데이터 크기는 반드시 char형 버퍼의 크기로 통일해주세요!
이번 꺼는 심플해서 따로 소스코드 같은 거 안 올려놓겠습니다
궁금한 부분이 있다면 댓글로 질문 주세요!
그러면 긴 글 봐주셔서 감사합니다~!!
'🧼C, C++ > 네트워크' 카테고리의 다른 글
다중 클라이언트 C++ TCP #2 (2) | 2020.11.05 |
---|---|
소켓 버퍼 비우기 C++ (0) | 2020.10.17 |
다중 클라이언트 C++ TCP #1 (0) | 2020.10.14 |
소켓 기본 틀 #2 (1) | 2020.10.13 |
소켓 파일전송 C++ #1 (0) | 2020.10.06 |
댓글