转载地址:
https://blog.csdn.net/wenhong609/article/details/8834534?utm_source=copy
红色字体我遇到的坑
// CP.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <BaseTsd.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 4096
#define PORT 12345
#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3
static int index = 0;
HANDLE hCompletion;
typedef struct _PER_HANDLE_DATA
{
SOCKET sock; sockaddr_in si;
}PER_HANDLE_DATA,*PPER_HANDLE_DATA;
typedef struct _PER_IO_DATA
{ OVERLAPPED overlapped;
WSABUF wsabuf;
char buffer[BUFFER_SIZE];
int operationType;
}PER_IO_DATA,*PPER_IO_DATA;
DWORD WINAPI ServerThread(LPVOID lParam);
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsa;
WORD vW = MAKEWORD(2, 2);
DWORD err = WSAStartup(vW, &wsa);
if(0 != err)
{
cerr << "socket error";
}
if(LOBYTE(wsa.wVersion) != 2 || HIBYTE(wsa.wVersion) != 2)
{
cerr << "socket error";
}
hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
HANDLE h_DoThread = CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0);
SOCKET sListen = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(PORT);
si.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(sListen, (SOCKADDR *)&si, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
cout << "bind error!";
}
listen(sListen, 5);
while (TRUE)
{
sockaddr_in RemoteInfo;
int RemoteLen = sizeof(sockaddr_in);
SOCKET AcceptClient = accept(sListen, (sockaddr *)&RemoteInfo, &RemoteLen);
PPER_HANDLE_DATA pPerHandleData = new PER_HANDLE_DATA;
pPerHandleData->sock = AcceptClient;
memcpy(&(pPerHandleData->si), &RemoteInfo, sizeof(sockaddr));
CreateIoCompletionPort((HANDLE)pPerHandleData->sock, hCompletion, (DWORD)pPerHandleData, 0);
PPER_IO_DATA pPer_IO_Data = new PER_IO_DATA;
pPer_IO_Data->operationType = OP_READ;
pPer_IO_Data->wsabuf.buf = pPer_IO_Data->buffer;
pPer_IO_Data->wsabuf.len = BUFFER_SIZE;
DWORD dwRecv;
DWORD dwFlags = 0;
memset(&pPer_IO_Data->overlapped,0,sizeof(pPer_IO_Data->overlapped));
WSARecv(pPerHandleData->sock, &(pPer_IO_Data->wsabuf), 1, &dwRecv, &dwFlags, &(pPer_IO_Data->overlapped), NULL);
}
return 0;
}
DWORD WINAPI ServerThread(LPVOID lParam)
{
HANDLE hCompletion = (HANDLE)lParam;
DWORD dwTrans;
PPER_HANDLE_DATA pPer_Handle_Data;
PPER_IO_DATA pPer_IO_Data;
while(TRUE)
{
bool bOk= GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPer_Handle_Data, (LPOVERLAPPED *)&pPer_IO_Data, INFINITE);
if(!bOk)
{
cout << GetLastError() << endl;
closesocket(pPer_Handle_Data->sock);
delete pPer_Handle_Data;
delete pPer_IO_Data;
continue;
}
if (dwTrans == 0 && pPer_IO_Data->operationType == OP_READ ||
pPer_IO_Data->operationType == OP_WRITE)
{
closesocket(pPer_Handle_Data->sock);
delete pPer_Handle_Data;
delete pPer_IO_Data;
continue;
}
switch (pPer_IO_Data->operationType)
{
cout << "Switch" << endl;
case OP_READ:
{
pPer_IO_Data->buffer[dwTrans] = '\0';
cout << pPer_IO_Data->buffer << endl;
index++;
cout << index << endl;
WSABUF wsabuf;
wsabuf.buf = pPer_IO_Data->buffer;
wsabuf.len = BUFFER_SIZE;
pPer_IO_Data->operationType = OP_READ;
DWORD flags = 0;
WSARecv(pPer_Handle_Data->sock, &wsabuf, 1, &dwTrans, &flags, &(pPer_IO_Data->overlapped), NULL);
}
}
}
}
//#include <WINSOCK2.H>
//#include <windows.h>
//#include <iostream>
//#include <basetsd.h>
//using namespace std;
//
//#pragma comment(lib,"ws2_32.lib")
//
//#define BUFFER_SIZE 4096
//#define PORT 12345
//
//
//#define OP_READ 1
//#define OP_WRITE 2
//#define OP_ACCEPT 3
//
//static int index=0;
//
//HANDLE hCompletion;
//typedef struct _PER_HANDLE_DATA
//{
// SOCKET sock;
// sockaddr_in si;
//}PER_HANDLE_DATA,*PPER_HANDLE_DATA;
//
//
//typedef struct _PER_IO_DATA
//{
// OVERLAPPED overlapped;
// WSABUF wsabuf;
// char buffer[BUFFER_SIZE];
// int operationType;
//}PER_IO_DATA,*PPER_IO_DATA;
//DWORD WINAPI ServerThread(LPVOID lParam);
//int main()
//{
// WSADATA wsa;
// WSAStartup(MAKEWORD(2,2),&wsa);
//
//
// hCompletion=::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
// HANDLE h_DoThread=CreateThread(NULL,0,ServerThread,(LPVOID)hCompletion,0,0);
//
// SOCKET sListen=socket(AF_INET,SOCK_STREAM,0);
// sockaddr_in si;
// si.sin_family=AF_INET;
// si.sin_port=htons(PORT);
// si.sin_addr.S_un.S_addr=INADDR_ANY;
// bind(sListen,(SOCKADDR *)&si,sizeof(SOCKADDR));
// listen(sListen,5);
//
// while(TRUE)
// {
// sockaddr_in RemoteInfo;
// int RemoteLen=sizeof(sockaddr_in);
// SOCKET AcceptClient=accept(sListen,(sockaddr*)&RemoteInfo,&RemoteLen);
// //每当有新连接时,将为其创建PER_HANDLE_DATA数据和PER_IO_DATA数据。
// //PER_HANDLE_DATA
// PPER_HANDLE_DATA pPerHandleData=new PER_HANDLE_DATA();
// pPerHandleData->sock=AcceptClient;
// memcpy(&(pPerHandleData->si),&RemoteInfo,sizeof(sockaddr));
// //将套接字句柄与完成端口相关联
// CreateIoCompletionPort((HANDLE)pPerHandleData->sock,hCompletion,
// (DWORD)pPerHandleData,0);
//
//
// //PER_IO_DATA
// PPER_IO_DATA pPer_IO_Data=new PER_IO_DATA();
// pPer_IO_Data->operationType=OP_READ;
// //WSARecv等函数中,缓冲区必须是WSABUF,下面对WSABUF进行初始化
//
// pPer_IO_Data->wsabuf.buf=pPer_IO_Data->buffer;
// pPer_IO_Data->wsabuf.len=BUFFER_SIZE;
// DWORD dwRecv;
// DWORD dwFlags=0;
//
// //
// memset(&pPer_IO_Data->overlapped,0,sizeof(pPer_IO_Data->overlapped));
// //投递一个接收请求
// ::WSARecv(pPerHandleData->sock,&(pPer_IO_Data->wsabuf),
// 1,&dwRecv,&dwFlags,&(pPer_IO_Data->overlapped),NULL);
//
// }
//
// return 0;
//}
//
//DWORD WINAPI ServerThread(LPVOID lParam)
//{
//
// HANDLE hCompletion=(HANDLE)lParam;
// DWORD dwTrans;
// PPER_HANDLE_DATA pPer_Handle_Data;
// PPER_IO_DATA pPer_IO_Data;
// cout<<"ServerThread"<<endl;
// while (TRUE)
// {
//
// bool bOk=GetQueuedCompletionStatus(hCompletion,&dwTrans,(LPDWORD)&pPer_Handle_Data,(LPOVERLAPPED*)&pPer_IO_Data,INFINITE);
// if(!bOk)
// {
// cout<<GetLastError()<<endl;
// //在此套接字上有错误发生
// closesocket(pPer_Handle_Data->sock);
//
// delete pPer_Handle_Data;
// delete pPer_IO_Data;
// continue;
// }
//
// //套接字被对方关闭
// if(dwTrans==0 && pPer_IO_Data->operationType==OP_READ || pPer_IO_Data->operationType==OP_WRITE )
// {
// closesocket(pPer_Handle_Data->sock);
// delete pPer_Handle_Data;
// delete pPer_IO_Data;
// continue;
// }
//
//
// switch(pPer_IO_Data->operationType)
// {
// cout<<"Switch"<<endl;
// case OP_READ:
// {
//
// pPer_IO_Data->buffer[dwTrans]='\0';
// cout<<pPer_IO_Data->buffer<<endl;
// index++;
// cout<<index<<endl;
//
//
// //继续投递IO操作
// WSABUF wsabuf;
// wsabuf.buf=pPer_IO_Data->buffer;
// wsabuf.len=BUFFER_SIZE;
// pPer_IO_Data->operationType=OP_READ;
// DWORD flags=0;
// WSARecv(pPer_Handle_Data->sock,&wsabuf,1,&dwTrans,&flags,&(pPer_IO_Data->overlapped),NULL);
//
// }
// case OP_WRITE:
// break;
// case OP_ACCEPT:
// break;
// }
// }
// return 0;
//}