Exemplo n.º 1
0
		void* RunFunc()
		{
			sockid = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
			sockaddr_in addr;
			addr.sin_port = htons(_unPort);
			addr.sin_family = AF_INET;
			inet_aton("127.0.0.1",&(addr.sin_addr));
			printf("begin to connect\n");
			if(!connect(sockid,(sockaddr*)&addr,sizeof(addr)))
			{
				printf("connected succcss\n");
				bool bCont = true;
				while(bCont)
				{
					if( Send() &&  Recv() )
					{
					}
					else
					{
						bCont = false;
					}
				}

			}
			else
			{
				printf("connected failed %d\n",errno);
			}
			CloseSock();
			Stop();
		}
Exemplo n.º 2
0
/**
* @author ACM2012
* @param [in] pReadQueue 读队列控制块结构, ReadQueue 读队列控制块句柄,SockMark 套接字标志
* @note    函数的主要功能是从应用程序写队列中读取数据并传送到传输层。函数提取
*/
void SockPool::WriteSock(HANDLE CH, unsigned int SockMark, HANDLE WriteQueue, PM pWriteQueue,HANDLE &SDestory)
{
	bool closeflag = false;
	int   readnum;
	while (SockMark2WriteState[SockMark]){
		HANDLE NewNode = CreateFileMapping(HANDLE(0xFFFFFFFF), NULL, PAGE_READWRITE, 0, sizeof(Node), NULL);
		PN pNode = (PN)MapViewOfFile(NewNode, FILE_MAP_WRITE, 0, 0, sizeof(Node));
        WaitForSingleObject(*SockMark2REvent[SockMark], INFINITE);///<等待传输层数据到来

		ClearNode(pWriteQueue);
		if (!SockDataToNode(pNode, SockMark))
			break;
		UnmapViewOfFile(pNode);
		SockMark2WEvent[SockMark]->SetEvent();
		AddToTail(pWriteQueue,NewNode);///<添加数据到写队列
		CloseHandle(NewNode);
	}
	ClearNode(pWriteQueue);///<释放写队列资源
	CloseHandle(pWriteQueue->Head);
	CloseHandle(pWriteQueue->Tail);
	CloseHandle(pWriteQueue->Cur);
	UnmapViewOfFile(pWriteQueue);
	CloseHandle(WriteQueue);
	SockMark2WriteState.erase(SockMark);
	SockMark2WEvent.erase(SockMark);
	if (SockMark2State[SockMark])
		CloseSock(SockMark);
	else
		SockMark2State[SockMark] = true;
}
Exemplo n.º 3
0
//---------------------------------------------------------------------------------------------------------------------------
//PostRecv()
//return -1 when error , else return 0
//---------------------------------------------------------------------------------------------------------------------------
int CIocpServer::PostRecv(SOCKET_OBJ *sock, BUFFER_OBJ *recvobj)
{
	WSABUF  wbuf;
	DWORD   bytes,
		flags;
	int     rc;

	if(recvobj->buflen >= DEFAULT_BUFFER_SIZE)
	{ 
#ifdef LOG_LEVEL2
		Log_Server.Write("(->%d)接收缓冲溢出",sock->s);
#endif
		CloseSock(sock);
		return -1;
	}

	recvobj->operation = OP_READ;

	wbuf.buf = recvobj->buf+recvobj->buflen;			//将接收缓冲定位到原来数据的末尾
	wbuf.len = DEFAULT_BUFFER_SIZE - recvobj->buflen;	//重新设置可接受数据的长度

	flags = 0;

	EnterCriticalSection(&sock->cs);

	rc = WSARecv(
		sock->s,
		&wbuf,
		1,
		&bytes,
		&flags,
		&recvobj->ol,
		NULL
		);

	if (rc == SOCKET_ERROR)
	{
		if (WSAGetLastError() != WSA_IO_PENDING) 
		{
#ifdef LOG_LEVEL2
			Log_Server.Write("(->%d)PostRecv错误: %d",sock->s,WSAGetLastError());
#endif           
			LeaveCriticalSection(&sock->cs);
			return SOCKET_ERROR;
		}
	}

	LeaveCriticalSection(&sock->cs);

#ifdef LOG_STATUS
	InterlockedIncrement(&gIoCount);
#endif

	return NO_ERROR;
}
Exemplo n.º 4
0
void DS::FreeSock(DS::SocketHandle sock)
{
    CloseSock(sock);
    delete reinterpret_cast<SocketHandle_Private*>(sock);
}
Exemplo n.º 5
0
/**
* @author ACM2012
* @param [in] CH 被服务程序句柄,pReadQueue 读队列控制块结构, ReadQueue 读队列控制块句柄,SockMark 套接字标志
* @note    函数的主要功能是从应用程序写队列中读取数据并传送到传输层。函数提取
*/
void SockPool::ReadSock(HANDLE CH, unsigned int SockMark, HANDLE ReadQueue, PM pReadQueue,HANDLE &CDestory)
{
	PN pCur = (PN)MapViewOfFile(pReadQueue->Cur, FILE_MAP_WRITE, 0, 0, sizeof(Node));//获取Cur映射内存块
	transstruct  AppData;
	HANDLE HData = NULL;
	portin myportsrc;
    CString myid;
	while (SockMark2ReadState[SockMark]) { ///<当状态变为false时退出
		if (pCur->Next == NULL){
			Sleep(100);
			continue;
		}
		CloseHandle(pReadQueue->Cur);//释放Cur
		DuplicateHandle(CH, pCur->Next, SH, &pReadQueue->Cur, NULL, true, DUPLICATE_SAME_ACCESS);
		UnmapViewOfFile(pCur);
		pCur = (PN)MapViewOfFile(pReadQueue->Cur, FILE_MAP_WRITE, 0, 0, sizeof(Node));

		PN pNode = (PN)MapViewOfFile(pReadQueue->Cur, FILE_MAP_WRITE, 0, 0, sizeof(Node));
		memset(&AppData, 0, sizeof(transstruct));///初始化为0
		
		myid.Format(_T("%s %d"), AfxGetApp()->m_lpCmdLine,pNode->FuncID);
		//AfxMessageBox(myid);
		switch (pNode->FuncID){///获取当前命令类型
		case SOCKBIND:
			Port2SockMark.erase(SockMark2Port[SockMark]);
			SockMark2Port.erase(SockMark);
			SockMark2Port[SockMark] = pNode->bindport;
			Port2SockMark[pNode->bindport] = SockMark;
			break;
		case SOCKACCEPT:
			memcpy(myportsrc.srcip, pNode->srcip, 20);
			myportsrc.srcport = pNode->srcport;
			myportsrc.dstport = SockMark2Port[SockMark];
			PortIn2ScokMark[myportsrc] = pNode->AcceptSockMark;
			Port2PortOut[SockMark2Port[pNode->AcceptSockMark]] = pNode->dstport;
			break;
		case SOCKSEND:
		case SOCKSENDTO: ///<发送数据
			memcpy(AppData.dstip, pNode->dstip, 20);
			AppData.dstport = pNode->dstport;
			AppData.datalength = pNode->DataLen;///<填充源端口
			AppData.srcport = (Port2PortOut.find(SockMark2Port[SockMark]) == Port2PortOut.end()) ? SockMark2Port[SockMark] : Port2PortOut[SockMark2Port[SockMark]];
			AppData.function = pNode->FuncID;
			DuplicateHandle(CH, pNode->Data, SH, &HData, NULL, true, DUPLICATE_SAME_ACCESS);
			AppData.data = (char *)MapViewOfFile(HData, FILE_MAP_WRITE, 0, 0, pNode->DataLen);
			AfxGetApp()->m_pMainWnd->SendMessage(TRANSTOIP, (WPARAM)&AppData, (LPARAM)pNode->FuncID);
			break;
		case SOCKCONNECT:
		case SOCKCLOSE:
			memcpy(AppData.dstip, pNode->dstip, 20);
			AppData.dstport = pNode->dstport;
			AppData.srcport = SockMark2Port[SockMark];
			AppData.function = pNode->FuncID;
			//if (pNode->FuncID == SOCKCONNECT)
			AfxGetApp()->m_pMainWnd->SendMessage(TRANSTOIP, (WPARAM)&AppData, (LPARAM)pNode->FuncID);
			break;
		case SOCKLISTEN:
			AppData.srcport  = SockMark2Port[SockMark];
			AppData.function = pNode->FuncID;
			AfxGetApp()->m_pMainWnd->SendMessage(TRANSTOIP, (WPARAM)&AppData, (LPARAM)pNode->FuncID);
			break;
		default:
			break;
		}
		if (AppData.data != NULL){
			UnmapViewOfFile(AppData.data);
			AppData.data = NULL;
		}
		if (HData != NULL){
			CloseHandle(HData);
			HData = NULL;
		}
		if (pNode->FuncID == SOCKCLOSE){
			sockconnum--;
			UnmapViewOfFile(pNode);
			break;
		}
		UnmapViewOfFile(pNode);
		pReadQueue->cid++;
		
	}
	UnmapViewOfFile(pCur);  ///<释放读队列资源
	SockMark2ReadState.erase(SockMark);
	UnmapViewOfFile(pReadQueue);
	CloseHandle(ReadQueue);
	ReleaseSemaphore(CDestory,1,NULL);
	if (SockMark2State[SockMark])
		CloseSock(SockMark);
	else
		SockMark2State[SockMark] = true;
}
Exemplo n.º 6
0
//如果发送队列存在,Send()首先尝试将数据添加到队列的最后一个BufferOBJ.如果BufferOBJ的可用空间不足,
//Send()将开辟一个新的BufferOBJ用于发送.当发送队列为空时,Send()将调用PostSend()立即提交一个发送操作
//
int CIocpServer::Send(SOCKET_OBJ *sock,const void * buffer,int len)//发送向客户端数据
{
	_ASSERTE(len <= DEFAULT_BUFFER_SIZE*MAX_UNSENDS_COUNT && len > 0);

	if(sock == NULL || len > DEFAULT_BUFFER_SIZE*MAX_UNSENDS_COUNT || len <= 0)
		return -1;

	BUFFER_OBJ * tmpbuf;
	int rc=NO_ERROR;

#ifdef DEBUG_IOCP
	_ASSERTE(sock->onclosed == 0); //已经调用过OnClose()还发?
	_ASSERTE(sock->freeed == 0);   //已经free掉了!
#endif

	InterlockedIncrement(&sock->sending_count); //为了安全的freeobj

	if( ( sock->flag_close == 0 ) || (sock->s == INVALID_SOCKET) )
	{
		InterlockedDecrement(&sock->sending_count);
		return -1;
	}

	int i=0;
	int len2=len;
	char *buf2;

	if(len2 > DEFAULT_BUFFER_SIZE)
		len2 = DEFAULT_BUFFER_SIZE;

	LOCK(&sock->cs);

	tmpbuf = sock->sendobj;
	if(tmpbuf == NULL)
	{ //发送队列为空
		tmpbuf = GetBufferObj();

#ifdef DEBUG_IOCP
		tmpbuf->sclient = sock->s;
#endif

		memcpy(tmpbuf->buf,buffer,len2);
		tmpbuf->buflen = len2;

		rc = PostSend(sock,tmpbuf);
		if(rc == 0)
			sock->sendobj = tmpbuf;
		else
			FreeBufferObj(tmpbuf);

	}
	else
	{  
		while(tmpbuf->next)
		{
			tmpbuf = tmpbuf->next;
			i++;
		}

		if(i > MAX_UNSENDS_COUNT) 
		{
			rc = -1;
			CloseSock(sock);
		} 
		else
		{
			if(tmpbuf->buflen + len2 > DEFAULT_BUFFER_SIZE)
			{

				tmpbuf->next = GetBufferObj();
				tmpbuf = tmpbuf->next;
			}
			memcpy(tmpbuf->buf+tmpbuf->buflen,buffer,len2);
			tmpbuf->buflen += len2;
		}
	}

	len -= len2;
	buf2 = (char *)buffer+len2;

	while(rc == 0 && len >0)
	{
		len2 = len;

		if(len2 > DEFAULT_BUFFER_SIZE)
			len2 = DEFAULT_BUFFER_SIZE;

		tmpbuf->next = GetBufferObj();
		tmpbuf = tmpbuf->next;

		memcpy(tmpbuf->buf,buf2,len2);
		tmpbuf->buflen = len2;
		len -= len2;
		buf2 += len2;
		i++;

		if(i > MAX_UNSENDS_COUNT)
		{
#ifdef LOG_LEVEL1
			Log_Server.Write("Send(): 发送失败(当前用户的发送队列超出 %d!",MAX_UNSENDS_COUNT);
#endif
			rc = -1;			
			break;
		}
	}

	UNLOCK(&sock->cs);

	InterlockedDecrement(&sock->sending_count);

	return rc;
	//注意:在PostSend()里面,buflen被设置为DEFAULT_BUFFER_SIZE,Send()调用时候的数据不会添加到正在发送的BufferObj后面
}