完成端口 内存错误

zwicker 2009-11-27 11:32:13
以下程序是用iocp写的flash安全策略文件,当进行压力测试时,很多线程连接到此程序,会出现内存不能为read/write的情况。请帮忙看看什么原因?


#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Winsock2.h>//加裁头文件
#include <stdio.h>//加载标准输入输出头文件
#include <iostream>
#include <string>
#include <sys/stat.h>
#include "zdk/zerolib/ztempl/zinifile.h"
#pragma comment(lib,"ws2_32.lib")
#define MAXMAN 2

using namespace std;

#define CP_RECV 1
#define CP_SEND 2

typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[100];
int OperateType;
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;

typedef struct
{
SOCKET Socket;
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;


static char PermissionStr[2048] ="";
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;



DWORD WINAPI ServerWorkerThread(LPVOID threadData);

int WriteToLog(char* str)
{
//获得程序路径
char szPathTemp[512];
GetModuleFileName(NULL, szPathTemp, 512);
for (int i=strlen(szPathTemp); i>=0; i--)
{
if (szPathTemp[i] == '\\')
{
szPathTemp[i] = '\0';
break;
}
}
strcat(szPathTemp,"\\status.txt");

//获取当前时间
char chBuf[500];
SYSTEMTIME stLocal;
::GetLocalTime(&stLocal);
sprintf(chBuf,_T("%u/%u/%u %02u:%02u:%02u "),
stLocal.wYear, stLocal.wMonth, stLocal.wDay,
stLocal.wHour, stLocal.wMinute, stLocal.wSecond);

strcat(chBuf,str);

struct stat statbuf;
FILE* log;
log = fopen(szPathTemp, "a+");
fstat(fileno(log),&statbuf);

if (statbuf.st_size>1024*1024)
{
fclose(log);
log=fopen(szPathTemp,"w+");
}

if (log == NULL){
OutputDebugString("Log file open failed.");
return -1;
}

fprintf(log, "%s\n", chBuf);
fclose(log);
return 0;
}



int main()
{
//获得程序路径
char szPathTemp[512];
GetModuleFileName(NULL, szPathTemp, 512);
for (int i=strlen(szPathTemp); i>=0; i--)
{
if (szPathTemp[i] == '\\')
{
szPathTemp[i] = '\0';
break;
}
}
strcat(szPathTemp,"\\config.ini");

CZIniFile m_InitFile;
if(! m_InitFile.LoadFromFile(szPathTemp))
{
WriteToLog("读取配置文件失败!");
return 0;
}
CZString * pstr = m_InitFile.GetSubTitleItem("NetConfig","port",0);
if( pstr == NULL)
{
WriteToLog("读取本地监听端口失败!");
return 0;
}
int m_iBindPort = pstr->ToIntD();
int countDomain = m_InitFile.GetSubTitleCount("DomainAndPort");

sprintf(PermissionStr,"<cross-domain-policy> \n");
for(int i=0; i<countDomain; i++)
{
int subTitleItemCount = 0;
char subTitleItemName[100] = "";
sprintf(subTitleItemName,"domainAndPort%d",i);

CZString strHost = "";
CZString strPort = "";
subTitleItemCount = m_InitFile.GetSubTitleItemCount("DomainAndPort",subTitleItemName);

for(int j=0; j<subTitleItemCount; j++)
{
pstr = m_InitFile.GetSubTitleItem("DomainAndPort",subTitleItemName,j);
if( pstr == NULL)
{
return 0;
}
if(j==0)
{
strHost = pstr->GetBuf();
}
else
{
strPort += pstr->GetBuf();
if(j!=subTitleItemCount-1)
{
strPort += ",";
}
}
}
char subStr[1000] = "";
sprintf(subStr,"<allow-access-from domain=\"%s\" to-ports=\"%s\" /> \n",strHost.GetBuf(),strPort.GetBuf());
strcat(PermissionStr,subStr);
}
strcat(PermissionStr,"</cross-domain-policy>");

SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
WSADATA wsaData;
DWORD Ret;

if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
WriteToLog("WSAStartup failed with error");
return 0;
}

if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
{
printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
WriteToLog("CreateIoCompletionPort failed with error");
WSACleanup();
return 0;
}

GetSystemInfo(&SystemInfo);


for(i = 0; i < SystemInfo.dwNumberOfProcessors*2; i++)
{
HANDLE ThreadHandle;

if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
0, &ThreadID)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
WriteToLog("CreateThread() failed with error");
WSACleanup();
return 0;
}

CloseHandle(ThreadHandle);
}

if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
WriteToLog("WSASocket() failed with error");
WSACleanup();
return 0;
}

InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(m_iBindPort);

if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
WriteToLog("bind() failed with error");
WSACleanup();
return 0;
}

if (listen(Listen, 5) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
WriteToLog("listen() failed with error");
WSACleanup();
return 0;
}
else
{
cout<<"<<<<<<<<<此程序只为FLASH提供安全策略。<<<<<<<"<<endl;
cout<<"安全策略文件内容如下:\n"<<PermissionStr<<endl;
cout<<"正在监听 "<<m_iBindPort<<" 端口......"<<endl;

char temp[2000];
sprintf(temp,"<<<<<<<<<此程序只为FLASH提供安全策略。<<<<<<<\n安全策略文件内容如下:\n%s\n正在监听 %d 端口......",PermissionStr,m_iBindPort);
WriteToLog(temp);
}

while(TRUE)
{
if ((Accept = WSAAccept(Listen, NULL, NULL, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
WriteToLog("WSAAccept() failed with error");
//WSACleanup();
//return 0;
//continue;
}

if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
WriteToLog("GlobalAlloc() failed with error");
//WSACleanup();
//return 0;
}

//printf("Socket number %d connected\n", Accept);

struct sockaddr_in peerAddr;
int iSize=sizeof(peerAddr);
if (SOCKET_ERROR==getpeername(Accept,(struct sockaddr *)&peerAddr,&iSize))
{
WriteToLog("获取远程连接信息失败!");
//WSACleanup();
//return 0;
}

char temp[500];
int port=ntohs(peerAddr.sin_port);
char *ipAddr=inet_ntoa(peerAddr.sin_addr);
sprintf(temp,"[ip]:%s[port]:%d连接到此端口!",ipAddr,port);
printf("%s\n",temp);
WriteToLog(temp);

PerHandleData->Socket = Accept;

if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData,0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
WriteToLog("CreateIoCompletionPort failed with error");
//WSACleanup();
//return 0;
}

if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
WriteToLog("GlobalAlloc() failed with error");
//WSACleanup();
//return 0;
}

ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->OperateType=CP_RECV;
PerIoData->DataBuf.len = 100;
PerIoData->DataBuf.buf = PerIoData->Buffer;

Flags = 0;

if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
WriteToLog("WSARecv() failed with error");
//WSACleanup();
//return 0;
}
}
}

WSACleanup();

return 0;
}

DWORD WINAPI ServerWorkerThread( LPVOID threadData )
{
HANDLE CompletionPort =(HANDLE)threadData;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;

while(TRUE)
{

if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}

if (PerIoData->OperateType == CP_RECV)
{
if(strcmp(PerIoData->DataBuf.buf,"<policy-file-request/>")==0)
{
//cout<<PerIoData->DataBuf.buf<<endl;
printf("通过验证,返回配置文件内容给客户程序!\n");

WriteToLog("通过验证,返回配置文件内容给客户程序!");

WSABUF sndBuf;
sndBuf.buf=PermissionStr;
sndBuf.len=strlen(PermissionStr)+1;

PerIoData->OperateType=CP_SEND;

if (WSASend(PerHandleData->Socket, &sndBuf, 1, &SendBytes, 0, &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
WriteToLog("WSASend() failed with error");
return 0;
}
}
}
closesocket(PerHandleData->Socket);
}

}



...全文
125 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
JonathanS666 2009-11-27
  • 打赏
  • 举报
回复
1、flash的策略文件不必加\n,它只是一个xml文件,另外你没有加头“<?xml version=\"1.0\" ?>”
2、CreateThread换成_beginthreadex,这样用c运行时库是安全的
Leo_red 2009-11-27
  • 打赏
  • 举报
回复
出现内存不能为read/write ,是不是就是冒出一个内存地址,然后说不能够read或者write。
那种最常见的就是数组越界阿。
CCPISDYING 2009-11-27
  • 打赏
  • 举报
回复
没看出什么来
只是工作线程内PerIoData->Overlapped发送前未重置,有可能和RECV用重了影响到PermissionStr争锁,不知有没有影响.
不知我说的没有有错,高手指正
hhwei1985 2009-11-27
  • 打赏
  • 举报
回复
up
zwicker 2009-11-27
  • 打赏
  • 举报
回复
对完成端口不是很了解,能不能帮忙看看程序有什么问题
WecanHuang 2009-11-27
  • 打赏
  • 举报
回复
那不是内存错误
是网络错误的一种报法
Wenxy1 2009-11-27
  • 打赏
  • 举报
回复
多线程环境,注意加锁保护公共资源,防止竞争条件。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧