ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • mfc - web 통신
    정보공유/공부 2023. 5. 16. 13:58

    MFC web 통신하는 법 까먹기 전에 기록해 놓는 용도

    web통신을 해야하는 경우가 생겨서 테스트 서버랑 만들어 봤다

    • server - python / Flask 로 구현
    • client - C++(MFC)
    • 주고받는 데이터 형식은 Json (rapidjson 사용)

     

    - web 접속을 도와주는 일반적인 HTTP 클라이언트 애플리케이션의 단계 | Microsoft Learn 설명서

     

    일반적인 HTTP 클라이언트 애플리케이션의 단계

    자세한 정보: 일반적인 HTTP 클라이언트 애플리케이션의 단계

    learn.microsoft.com

    - cpp에서 json데이터를 다른 손질 없이 사용할 수 있게 만들어주는 rapidjson 설명서 / 깃 접속 링크입니다.

     

    RapidJSON: Main Page

    A fast JSON parser/generator for C++ with both SAX/DOM style API Tencent is pleased to support the open source community by making RapidJSON available. Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. Build status Introduction RapidJSON

    rapidjson.org

     

    - 참조파일

    #include "afxinet.h"
    #include "rapidjson/document.h"
    #include "rapidjson/writer.h"
    #include "rapidjson/prettywriter.h"
    #include "rapidjson/stringbuffer.h"
    #include "rapidjson/pointer.h"
    #include "rapidjson/rapidjson.h"
    using namespace rapidjson;

     

     

    server -  단순하게 아무 요청이 들어오면 데이터를 바로 리턴

    from http import HTTPStatus
    import requests
    from flask import Flask, jsonify, redirect, render_template, request, url_for
    
    app = Flask(__name__)
    
    RepliedLotInfo = [response 값]
    
    
    @app.route('/<info>', methods=['POST', 'GET'])
    def hello(info):
    	#LotInfo = requests.get()
    	return jsonify(RepliedLotInfo)
    
    
    if __name__ == "__main__":
    	app.run(host='0.0.0.0', debug=True)

     

     

    client - 임시로 MFC에서 버튼을 누르면 웹에 접속

    void CMlccVisionView::ClickBtn3dInspStart2()
    {
    	CString IP = L"192.168.50.181";
    	INTERNET_PORT nPort(5000);
    	CInternetSession session; // 세션 만들기
    	CHttpConnection* pConnection;
    	CHttpFile* pFile;
    	Document doc;
    	CString strHeader = _T("Content-Type: application/x-www-form-urlencoded\r\n");
    	DWORD dwRet;
    	int nRead = 0;
    	char* pszBuff = new char[2000000];
    	memset(pszBuff, 0, sizeof(pszBuff));
    	CString sendMsg = _T("{ \"LOT\" : \"\", \"DBLINK\" : \"CLS\" }");// server에 보낼 정보
    
    
    	pConnection = session.GetHttpConnection(IP, nPort); // 주소 연결
    	pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, sendMsg); // 연결 방식 설정HTTP_VERB_POST도 있음
    
    	// 보낸 데이터 로그 기록
    	Weblogfile.msg.Format(sendMsg);
    	Weblogfile.send();
    
    	BOOL result = pFile->SendRequest(strHeader, (LPVOID)(LPCTSTR)sendMsg, sendMsg.GetLength()); // 프로그램 -> 서버 데이터 전송
    
    	if (result != 0)
    	{
    		CString responeLength;
    		pFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, responeLength); // respone되는 파일크기 받기
    		pFile->QueryInfoStatusCode(dwRet); // 파일전송 상태 알 수 있음
    
    		if (dwRet == HTTP_STATUS_OK)
    		{
    			while ((nRead = pFile->Read(pszBuff, 2000000 - 1)) > 0)
    			{
    				pszBuff[nRead] = 0;
    				
    				doc.Parse(pszBuff);
    				if (doc.IsArray())
    				{// json array 로 넘어오면 하나하나 읽어줘야함
    					for (SizeType i = 0; i < doc.Size(); i++)
    					{
    						Value& v = doc[i];
    						CString project = CA2T(v["PART_NAME"].GetString(), CP_UTF8);
    					}
    					/*
    					for (Value::ConstValueIterator itr = doc.Begin(); itr != doc.End(); ++itr)
    					{//첫번째 json부터 읽음					
    						const Value& cmd = *itr;
    						// 						bool object = itr->IsObject();
    						for (Value::ConstMemberIterator cmdItr = cmd.MemberBegin(); cmdItr != cmd.MemberEnd(); ++cmdItr)
    						{
    							const char* reKey = cmdItr->name.GetString();
    							const char* reValue = cmdItr->value.GetString();
    
    							Weblogfile.msg.Format(L"%s : %s ", reKey, reValue);
    							Weblogfile.response();
    						}
    						
    						Weblogfile.responseEnd();
    					}
    					//Value& v = doc[0][0]["PART_NAME"];
    */
    				}
    
    				//Value& v = doc;
    				//CString project = CA2T(doc["PART_NAME"].GetString(), CP_UTF8);			
    			};
    
    			delete[] pszBuff;
    		}
    		else {
    			
    		}
    	}
    
    
    	if (pFile) {
    		pFile->Close();
    		delete pFile;
    	}
    
    	if (pConnection) {
    		pConnection->Close();
    		delete pConnection;
    	}
    
    	//pFile->WriteString(strData);//블록으로 데이터를 보낼수 있음
    	session.Close();
    
    }

     

     

    코드 설명

    - 변수 설정

    	CString IP = L"192.168.50.181";
    	INTERNET_PORT nPort(5000);
    	CInternetSession session; // 세션 만들기
    	CHttpConnection* pConnection;
    	CHttpFile* pFile;
    	Document doc;
    	CString strHeader = _T("Content-Type: application/x-www-form-urlencoded\r\n");
    	DWORD dwRet;
    	int nRead = 0;
    	char* pszBuff = new char[2000000];
    	memset(pszBuff, 0, sizeof(pszBuff));
    	CString sendMsg = _T("{ \"LOT\" : \"\", \"DBLINK\" : \"CLS\" }");// server에 보낼 정보

     

    - web 접속 및 요청

    	pConnection = session.GetHttpConnection(IP, nPort); // 주소 연결
    	pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, sendMsg); // 연결 방식 설정HTTP_VERB_POST도 있음
    
    	BOOL result = pFile->SendRequest(strHeader, (LPVOID)(LPCTSTR)sendMsg, sendMsg.GetLength()); // 프로그램 -> 서버 데이터 전송
    if (result != 0)
    	{
    		CString responeLength;
    		pFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, responeLength); // respone되는 파일크기 받기
    		pFile->QueryInfoStatusCode(dwRet); // 파일전송 상태 알 수 있음
    
    		if (dwRet == HTTP_STATUS_OK)
    		{
    			while ((nRead = pFile->Read(pszBuff, 2000000 - 1)) > 0)
    			{
    				pszBuff[nRead] = 0;
    				
    				doc.Parse(pszBuff);
                    // 서버에서 JsonArray로 넘어오기 때문에 데이터에 인덱스 접근
    				if (doc.IsArray())
    				{// json array 로 넘어오면 하나하나 읽어줘야함
    					for (SizeType i = 0; i < doc.Size(); i++)
    					{
    						Value& v = doc[i];
    						CString project = CA2T(v["PART_NAME"].GetString(), CP_UTF8);
    					}
    					/*
    					for (Value::ConstValueIterator itr = doc.Begin(); itr != doc.End(); ++itr)
    					{//첫번째 json부터 읽음					
    						const Value& cmd = *itr;
    						// 						bool object = itr->IsObject();
    						for (Value::ConstMemberIterator cmdItr = cmd.MemberBegin(); cmdItr != cmd.MemberEnd(); ++cmdItr)
    						{
    							const char* reKey = cmdItr->name.GetString();
    							const char* reValue = cmdItr->value.GetString();
    
    							Weblogfile.msg.Format(L"%s : %s ", reKey, reValue);
    							Weblogfile.response();
    						}
    						
    						Weblogfile.responseEnd();
    					}
    					//Value& v = doc[0][0]["PART_NAME"];
    */
    				}
    
    				//Value& v = doc;
    				//CString project = CA2T(doc["PART_NAME"].GetString(), CP_UTF8);			
    			};
    
    			delete[] pszBuff;
    		}
    		else {
    			
    		}
    	}

     

    댓글

Designed by Tistory.