Commit 720cf5c9 by NitefullWind

1. 实现收数据时接收处理消息头。2. 导出函数参数增加缓冲区大小。 3. 添加日志打印。

parent e06e76de
...@@ -5,4 +5,6 @@ ipch/ ...@@ -5,4 +5,6 @@ ipch/
*.suo *.suo
*.user *.user
*.filters *.filters
*.db *.db
\ No newline at end of file *.txt
*.opensdf
\ No newline at end of file
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
//#define SERVERIP "172.16.13.87" //#define SERVERIP "172.16.13.87"
#define SERVERPORT 23770 #define SERVERPORT 23770
#define FM_ERROR_SOCKET "{\"statusCode\": 104, \"msg\": \"本地Socket通讯错误.\"}"
#define FM_ERROR_TIMEOUT "{\"statusCode\": 104, \"msg\": \"本地Socket通讯超时.\"}"
#define MakeError(msg, ...) \ #define MakeError(msg, ...) \
strset(ErrorMsg, 0); \ strset(ErrorMsg, 0); \
sprintf(ErrorMsg, msg, __VA_ARGS__); \ sprintf(ErrorMsg, msg, __VA_ARGS__); \
...@@ -26,7 +23,7 @@ ...@@ -26,7 +23,7 @@
isOk = false; isOk = false;
extern "C" { extern "C" {
__declspec(dllexport) int __stdcall FMGetResponse(const char* req, char* rsp) __declspec(dllexport) int FMGetResponse(const char* req, char* rsp, unsigned int byteSize)
{ {
WSADATA wsa; WSADATA wsa;
SOCKET _socket; SOCKET _socket;
...@@ -36,7 +33,7 @@ extern "C" { ...@@ -36,7 +33,7 @@ extern "C" {
Freemud::Error _error; Freemud::Error _error;
char ErrorMsg[1000] = {0}; char ErrorMsg[1000] = {0};
Log("Initialising Winsock..."); //Log("Initialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{ {
MakeError("Error. Startup error: %d. Server: %s, Port: %d", WSAGetLastError(), SERVERIP, SERVERPORT) MakeError("Error. Startup error: %d. Server: %s, Port: %d", WSAGetLastError(), SERVERIP, SERVERPORT)
...@@ -71,11 +68,16 @@ extern "C" { ...@@ -71,11 +68,16 @@ extern "C" {
int recv_size = SOCKET_ERROR; int recv_size = SOCKET_ERROR;
//if (isOk && (recv_size = recv(_socket, rsp, 40960, 0)) == SOCKET_ERROR) //if (isOk && (recv_size = recv(_socket, rsp, 40960, 0)) == SOCKET_ERROR)
//if (isOk && (recv_size = readline(_socket, rsp, 40960)) == SOCKET_ERROR) //if (isOk && (recv_size = readline(_socket, rsp, 40960)) == SOCKET_ERROR)
if (isOk && (recv_size = Recv(_socket, rsp)) == SOCKET_ERROR) memset(rsp, 0, byteSize);
if (isOk && (recv_size = Recv(_socket, rsp, byteSize-1)) == SOCKET_ERROR)
{ {
MakeError("Error. Recv error: %d. Server: %s, Port: %d", WSAGetLastError(), SERVERIP, SERVERPORT) MakeError("Error. Recv error: %d. Server: %s, Port: %d", WSAGetLastError(), SERVERIP, SERVERPORT)
} else if(recv_size == 0) { } else if(recv_size == FMError_ConnectClosed.Code()) {
MakeError("Error. Connect closed: %d. Server: %s, Port: %d", WSAGetLastError(), SERVERIP, SERVERPORT) MakeError("Error. %s(%d). Server: %s, Port: %d", FMError_ConnectClosed.MsgCStr(), WSAGetLastError(), SERVERIP, SERVERPORT)
} else if(recv_size == FMError_IncorrectHeader.Code()) {
MakeError("Error. %s. Server: %s, Port: %d", FMError_IncorrectHeader.MsgCStr(), SERVERIP, SERVERPORT)
} else if(recv_size == FMError_BufferOverflow.Code()) {
MakeError("Error. %s. Server: %s, Port: %d", FMError_BufferOverflow.MsgCStr(), SERVERIP, SERVERPORT)
} }
if (isOk) { if (isOk) {
......
No preview for this file type
...@@ -143,6 +143,8 @@ ...@@ -143,6 +143,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="fmerror.h" /> <ClInclude Include="fmerror.h" />
<ClInclude Include="fm_log.h" />
<ClInclude Include="fm_tool.h" />
<ClInclude Include="recv.h" /> <ClInclude Include="recv.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="send.h" /> <ClInclude Include="send.h" />
......
#ifndef FM_LOG_H
#define FM_LOG_H
#include "fm_tool.h"
#include <time.h>
#include <direct.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
class LOG
{
public :
LOG()
{
std::string filepath;
time_t tt = time(NULL);
tm *t = localtime(&tt);
fm_tool::GetProcPath(filepath);
Get_LOG_FileName();
filepath.append("fmdlllog\\");
mkdir(filepath.c_str());
filepath.append(_curr_filename);
filepath.append(".txt");
//std::cout << filepath << std::endl;
_filestm.open(filepath, std::ios::app);
if(_filestm.is_open())
{
_filestm << t->tm_year + 1900 << "-" << t->tm_mon + 1 << "-" << t->tm_mday << " " << t->tm_hour << ":" << t->tm_min << ":" << t->tm_sec << ":";
std::cout << t->tm_year + 1900 << "-" << t->tm_mon + 1 << "-" << t->tm_mday << " " << t->tm_hour << ":" << t->tm_min << ":" << t->tm_sec << ":";
_filestm.flush();
}
}
~LOG()
{
if(_filestm.is_open())
{
_filestm << std::endl;
std::cout << std::endl;
_filestm.flush();
_filestm.close();
}
}
void Get_LOG_FileName()
{
time_t tt = time(NULL);
tm *t = localtime(&tt);
std::stringstream sstr;
sstr << "FreemudAPI" << t->tm_year + 1900 << t->tm_mon + 1 << t->tm_mday;
std::string filename = std::string(sstr.str().c_str());
if(filename.compare(_curr_filename) != 0)
_curr_filename = filename;
}
template<typename T>
LOG& operator << (const T &in)
{
if(_filestm.is_open())
{
_filestm << in ;
std::cout << in ;
_filestm.flush();
}
return (*this);
}
private:
std::ofstream _filestm;
std::string _curr_filename;
};
#endif
\ No newline at end of file
#ifndef FM_TOOL
#define FM_TOOL
#include <string>
#ifdef WIN32
#include <windows.h>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#endif
#define MAX_INI_LEN 1024
using std::string;
class fm_tool
{
public:
static void GetProcPath(char * pathBuf)
{
#ifdef WIN32
int curPos;
GetModuleFileNameA((HMODULE)&__ImageBase, pathBuf, MAX_PATH);
curPos = strlen(pathBuf) - 1;
while('\\' != pathBuf[curPos])
{
curPos--;
}
curPos++;
pathBuf[curPos] = '\0';
#endif
}
static void GetProcPath(std::string &str)
{
#ifdef WIN32
int curPos;
char pathBuf[MAX_PATH] = { 0 };
GetModuleFileNameA((HMODULE)&__ImageBase, pathBuf, MAX_PATH);
curPos = strlen(pathBuf) - 1;
while('\\' != pathBuf[curPos])
{
curPos--;
}
curPos++;
pathBuf[curPos] = '\0';
str = std::string(pathBuf);
#endif
};
static bool ReadTMPForType(string path, string setion, string key, string &value, int maxbuflen = (MAX_INI_LEN))
{
char *valuebuf = (char *)malloc(maxbuflen * sizeof(char));
memset(valuebuf, 0, maxbuflen);
GetPrivateProfileStringA(setion.c_str(), key.c_str(), "", valuebuf, maxbuflen, path.c_str());
value.clear();
value = string(valuebuf);
free(valuebuf);
return value.empty();
}
};
#endif
\ No newline at end of file
#pragma once
#include <string> #include <string>
namespace Freemud namespace Freemud
...@@ -27,6 +29,12 @@ namespace Freemud ...@@ -27,6 +29,12 @@ namespace Freemud
{ {
} }
~Error()
{
int i = 0;
i++;
}
Error& operator = (const Error &rhs) Error& operator = (const Error &rhs)
{ {
this->_code = rhs.Code(); this->_code = rhs.Code();
...@@ -58,6 +66,9 @@ namespace Freemud ...@@ -58,6 +66,9 @@ namespace Freemud
std::string Msg() const { std::string Msg() const {
return this->_msg; return this->_msg;
} }
const char * MsgCStr() const {
return this->_msg.c_str();
}
private: private:
int _code; int _code;
......
#pragma once
#include "stdafx.h" #include "stdafx.h"
#include "socketHeader.h"
int _Recv(SOCKET socket, char *ptr, int length)
{
int totalLen = 0;
do {
if( (totalLen = recv(socket, ptr, length, 0)) < 0) {
if (totalLen == EINTR) {
Log("Error: EINTR.");
continue;
}
Log("Error: other recv error.");
return totalLen;
} else if( totalLen == 0) {
Log("Error: connect closed.");
return 0;
}
Log("Total: Size:%d, Data:%s", totalLen, ptr);
} while(0);
return totalLen;
}
int Recv(SOCKET socket, char *ptr) int Recv(SOCKET socket, char *ptr, unsigned int byteSize)
{ {
int tempLen = -1, totalLen = 0, needLen = -1; char *recvBuf = new char[byteSize+sizeof(FMSOCKHEADER)+1];
char tempBuf[MAX_SIZE+1] = {0}; memset(recvBuf, 0, byteSize+sizeof(FMSOCKHEADER)+1);
char *tempBuf = new char[MAX_SIZE+1];
int tempLen = -1, needLen = -1, totalLen = 0, dataLen = 0;
while(needLen == -1 || totalLen < needLen) {
memset(tempBuf, 0, MAX_SIZE+1);
if( (tempLen = _Recv(socket, tempBuf, MAX_SIZE)) <= 0) {
delete[] recvBuf;
delete[] tempBuf;
return tempLen; // 接收时错误
}
memcpy(recvBuf+totalLen, tempBuf, tempLen); // 临时数据拷贝到接收数据
totalLen += tempLen;
#ifdef NeedSocketHeaderRecv #ifdef NeedSocketHeaderRecv
if(needLen == -1 && totalLen >= sizeof(FMSOCKHEADER)) { // 如果消息头接收完成
FMSOCKHEADER header = {0,0,0};
memcpy(&header, recvBuf, sizeof(FMSOCKHEADER));
if(header.flag != FMHEADERFLAG) {
delete[] recvBuf;
delete[] tempBuf;
return FMError_IncorrectHeader.Code(); // 消息头不符
} else {
needLen = header.len + sizeof(FMSOCKHEADER); // 设置实际需要接收长度
dataLen = header.len;
#else if (byteSize < dataLen) { // 判断接收Buffer长度是否足够
#endif Log("Error. Buffer overflow, Except size: %d, Actual size: %d", byteSize, dataLen);
while(totalLen ==0 || totalLen < needLen) { delete[] recvBuf;
strset(tempBuf, 0); delete[] tempBuf;
if( (tempLen = recv(socket, tempBuf, MAX_SIZE, 0)) < 0) { return FMError_BufferOverflow.Code();
if (tempLen == EINTR) { }
Log("Error: EINTR.\n");
continue;
} }
Log("Error: other recv error.\n");
return tempLen;
} else if( tempLen == 0) {
Log("Error: connect closed.\n");
return 0;
} else {
strcpy(ptr+totalLen, tempBuf);
totalLen += tempLen;
Log("Temp: Size:%d, Data:%s\n", tempLen, tempBuf);
Log("Total: Size:%d, Data:%s\n", totalLen, ptr);
} }
#else
needLen = totalLen;
dataLen = totalLen;
if (byteSize < dataLen) { // 判断接收Buffer长度是否足够
delete[] recvBuf;
delete[] tempBuf;
return FMError_BufferOverflow.Code();
}
#endif
} }
return totalLen;
#ifdef NeedSocketHeaderRecv
memcpy(ptr, recvBuf+sizeof(FMSOCKHEADER), dataLen);
#else
memcpy(ptr, recvBuf, needLen);
#endif
delete[] recvBuf;
delete[] tempBuf;
return dataLen;
} }
static int read_cnt; static int read_cnt;
......
#pragma once
#include "stdafx.h" #include "stdafx.h"
#include "socketHeader.h" #include "socketHeader.h"
...@@ -14,10 +16,11 @@ int Send(SOCKET socket, const char *ptr) ...@@ -14,10 +16,11 @@ int Send(SOCKET socket, const char *ptr)
#endif #endif
int tempLen = -1; int tempLen = -1;
if( (tempLen = send(socket, sendData, sendLength, 0)) < 0) { if( (tempLen = send(socket, sendData, sendLength, 0)) < 0) {
Log("Error: other error.\n"); Log("Error: other error.");
return tempLen;
} else {
// Log("Total: Size:%d, Data:%s\n", tempLen, ptr);
return tempLen;
} }
#ifdef NeedSocketHeaderSend
delete[] addHeaderData;
#endif
return tempLen;
} }
\ No newline at end of file
#pragma once
#include "stdafx.h" #include "stdafx.h"
#define FMHEADERFLAG 0x4d46
typedef struct { typedef struct {
unsigned int flag; // 固定值 0x4d46 unsigned int flag; // 固定值 0x4d46
...@@ -24,7 +28,7 @@ int GetAddHeaderReqData(const char *originData, char *addHeaderReqData, unsigned ...@@ -24,7 +28,7 @@ int GetAddHeaderReqData(const char *originData, char *addHeaderReqData, unsigned
// 设置消息头的值 // 设置消息头的值
FMSOCKHEADER header = {0, 0, 0}; FMSOCKHEADER header = {0, 0, 0};
header.flag = 0x4d46; header.flag = FMHEADERFLAG;
header.len = originLen; header.len = originLen;
header.ver = 0x2; header.ver = 0x2;
......
...@@ -17,18 +17,27 @@ ...@@ -17,18 +17,27 @@
#include <errno.h> #include <errno.h>
#include <winsock2.h> #include <winsock2.h>
#include <Windows.h> #include <Windows.h>
#include "fmerror.h"
#include "fm_log.h"
//#define Log(_Format, ...) {char msg[1024] = {0}; printf("Function:%s, Line:%d: ", __FUNCTION__, __LINE__); printf(_Format, __VA_ARGS__); printf("\n");}
#define Log(_Format, ...) {printf("Function:%s, Line:%d: ", __FUNCTION__, __LINE__); printf(_Format, __VA_ARGS__); printf("\n");} #define Log(_Format, ...) {char msg[1024] = {0};sprintf(msg, _Format, __VA_ARGS__);LOG() << msg;}
const int MAX_SIZE = 4096; const int MAX_SIZE = 4096;
// 设置超时时间 // 设置超时时间
const int sendTimeOut = 0.5 * 60 * 1000; const int sendTimeOut = 0.5 * 60 * 1000;
const int recvTimeOut = 0.5 * 60 * 1000; const int recvTimeOut = 2 * 60 * 1000;
#ifndef NeedSocketHeaderSend #ifndef NeedSocketHeaderSend
#define NeedSocketHeaderSend #define NeedSocketHeaderSend
#endif #endif
#ifndef NeedSocketHeaderRecv #ifndef NeedSocketHeaderRecv
#define NeedSocketHeaderRecv #define NeedSocketHeaderRecv
#endif #endif
\ No newline at end of file
static const Freemud::Error FMError_Success(100, "Success.");
static const Freemud::Error FMError_ConnectClosed(0, "Connection closed.");
static const Freemud::Error FMError_SocketError(-1, "Socket error.");
static const Freemud::Error FMError_ConnectTimeout(-2, "Connection timeout.");
static const Freemud::Error FMError_IncorrectHeader(-3, "Incorrect socket's header.");
static const Freemud::Error FMError_BufferOverflow(-4, "Buffer overflow.");
\ No newline at end of file
...@@ -3,15 +3,27 @@ ...@@ -3,15 +3,27 @@
## 导出函数 ## 导出函数
```c++ ```c++
int FMGetResponse(const char *req, char *rsp) int FMGetResponse(const char *req, char *rsp, unsigned int byteSize)
``` ```
#### 参数 #### 参数
- req: 请求Json字符 - req: 请求Json字符
- rsp: 响应Json字符 - rsp: 接收响应Json字符的缓冲区
- bytesSize: rsp缓冲区的字节数大小(包括结束符)
#### 返回 #### 返回
返回收到的数据长度。如果为负数则代表出错。 返回正数则代表响应的数据长度。
如果为非正数则代表出错。
#### 返回值说明
| 返回值 | 说明 |
| -- | -- |
| 正数 | 收到的响应字节数 |
| 0 | Socket连接被断开 |
| -1 | Socket错误 |
| -2 | Socket接收或发送数据超时 |
| -3 | 消息头不合法 |
| -4 | 缓冲区不足 |
\ No newline at end of file
// test.cpp : 定义控制台应用程序的入口点。 // test.cpp : 定义控制台应用程序的入口点。
// //
#include "stdafx.h" #include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
EXTERN_C typedef int (__stdcall *FMGetResponse)(const char* req, char* rsp); typedef int (*FMGetResponse)(const char* req, char* rsp, unsigned int byteSize);
const unsigned int outSize = 1024*1024+1;
char out[outSize] = { 0 };
int _tmain(int argc, _TCHAR* argv[]) int _tmain(int argc, _TCHAR* argv[])
{ {
HMODULE hdll = LoadLibraryA("FreemudAPI.dll"); HMODULE hdll = LoadLibraryA("FreemudAPI.dll");
...@@ -21,20 +25,60 @@ int _tmain(int argc, _TCHAR* argv[]) ...@@ -21,20 +25,60 @@ int _tmain(int argc, _TCHAR* argv[])
exit(0); exit(0);
} }
//char req[] = {"I'm test request data."}; ////char req[] = {"I'm test request data."};
char req[] = {"{\"fm_cmd\": 10031}"}; //char req[] = {"{\"fm_cmd\": 1001}"};
//char bigReq[4096] = {0}; ////char bigReq[4096] = {0};
//for(int i=0; i<4096; i++) { ////for(int i=0; i<4096; i++) {
// bigReq[i] = 'a'; //// bigReq[i] = 'a';
//} ////}
char rsp[40960] = {0}; //char rsp[4096] = {0};
int ret = fmFunc(req, rsp); //int ret = fmFunc(req, rsp);
printf("================================================\n" //printf("================================================\n"
"Code: %d\n" // "Code: %d\n"
"Data: %s\n", ret, rsp); // "Data: %s\n", ret, rsp);
//system("pause");
//char fileName[80] = { 0 };
//char str[80] = { 0 };
do {
std::string fileName("");
std::string str("");
printf("Input file name(Quit with 'q'): ");
std::cin >> str;
std::string inStr("");
if(str == "q"){
break;
return 0;
}
else {
fileName = str + ".txt";
std::ifstream infile;
infile.open(fileName);
if(!infile) {
printf("Unable to open file: %s.txt[errno:%d]\n", str.c_str(), errno);
continue;
}
std::string tempStr="";
while(std::getline(infile, tempStr)){
inStr += tempStr;
}
printf("%s\n", inStr.data());
infile.close();
}
printf("Get in data: %s\n", inStr.data());
system("pause"); fmFunc(inStr.data(), out, outSize);
printf("========================================================================\n");
printf("\n%s\n", out);
printf("\n======================================================================\n");
}while(true);
return 0; return 0;
} }
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<ExecutablePath>E:\Code\FreemudAPI\x64\Release;$(ExecutablePath)</ExecutablePath> <ExecutablePath>E:\Code\FreemudAPI\x64\Release;$(ExecutablePath)</ExecutablePath>
<TargetName>$(ProjectName)_x64</TargetName> <TargetName>$(ProjectName)</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment