主要参考1程序:http://blog.youkuaiyun.com/u010025913/article/details/24467351 点击打开链接
主要参考2理论:完成端口的原理我是看的迷糊,还是要看看那篇百度首页大神(小猪)的解读。
现在我的疑问是:
1.是否在完成端口投递的每个异步操作时,都需要新建一个重叠结构OVERLAPPED。因为在参考1中,只是将原来的重叠结构清0.但是在后续的客户端断开后操作之后可能要释放这些内存,这块比较麻烦。
2.在设计通信之间的逻辑时,简直麻烦死了。要服务器针对每个客户端的操作来设计逻辑。(也可能是我思路不对)所以想求一个比较好的完成端口例子。
接下来是我的控制台程序代码:
1.客户端. 采用多线程来模拟两个不同的客户端访问服务器。
头文件 connet.h
#pragma once
#include <iostream>
#include <windows.h>
#include < Ws2bth.h >
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define MAX_CONCURRENT 2000 // 并发线程最大数
#define IP "192.168.1.185" // 服务器端IP地址
#define PORT 123456 // 服务器端口号
struct MyStruct
{
SOCKET soc; // SOCKET
char wStr[512] = { '0' }; // 日志字符串
};
MyStruct mystruct[1024];//结构体数组
class CSOCKET
{
public:
// 加载Winsock库
static BOOL WSAInit();
// 连接服务器端并发送数据
static BOOL ConnectA(DWORD threadID);
static BOOL ConnectB(DWORD threadID);
// 线程函数
static unsigned int __stdcall _ThreadFuncA();
static unsigned int __stdcall _ThreadFuncB();
// 清理工作
static BOOL Clean(SOCKET sockClient);
};
工程cpp文件 clientMain.cpp(这个文件是以前的一个文件改的,有一些无关的变量没有删去)
#include <process.h>
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include "Connect.h"
using namespace std;
int time;//线程持续时间
volatile long g_ncountright = 0;//全局变量计算多个线程累计成功发送多少条log信息
volatile long g_ncountwrong = 0;//全局变量计算多个线程累计失败发送了多少条log信息
volatile long g_ncountThread = 0;//全局变量计算多少个线程
// This function returns a pointer to a new string
// consisting of the first n characters in the str string.
char * left(const char * str, int n)
{
if (n < 0)
n = 0;
char * p = new char[n + 1];
int i;
for (i = 0; i < n && str[i]; i++)
p[i] = str[i]; // copy characters
while (i <= n)
p[i++] = '\0'; // set rest of string to '\0'
return p;
}
int SendDataToSocketServer(SOCKET socketL, const char * cSendData)
{
Sleep(10);
int Flag = send(socketL, cSendData, strlen(cSendData), 0);
if (Flag == SOCKET_ERROR)
{
return 444;//如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话那么send函数也返回SOCKET_ERROR
}
else
{
return Flag;//返回实际copy到发送缓冲区的的字节数
}
}
int RecvDataToSocketClient(SOCKET socketL, char * cSendData)
{
if (recv(socketL, cSendData, strlen(cSendData), 0) == SOCKET_ERROR)
{
return FALSE;
}
return TRUE;
}
/**********************************************************************
Description: :客户端执行发,收的逻辑程序
Input : 客户端所用的线程ID
***********************************************************************/
//发送PIN码的客户端A
int DataIntegrationA(SOCKET socketL, DWORD threadID)
{
int k = GetTickCount();
int oldK = k;//确定循环发送体的起始时间
int currK = k;
//定义并初始化客户端A要发送给服务器的PIN码
char message[40] = {0};
sprintf(message, "%s%d%s", "hello<TID:", threadID, ">");
//在一段时间内time持续发送
while (currK < (k + time))
{
oldK = currK;//
Sleep(1000);
//发送
int Sendflag = SendDataToSocketServer(socketL, message);
//发送失败
if (Sendflag == 444)
{
//找发送失败原因
printf("\n<线程 %d>客户端发送已经被服务器切断 %d\n", threadID, WSAGetLastError());
return 1;
}
else
{
//接收
cout << "["<<threadID<<"]" << "发给中转站:" << message << endl;
}
currK = GetTickCount();//更新当前运行时间,循环体执行判断
}
return 0;
}
//接收PIN码的客户端
int DataIntegrationB(SOCKET socketL, DWORD threadID)
{
int k = GetTickCount();
int oldK = k;//确定循环发送体的起始时间
int currK = k;
//定义并初始化客户端从服务器收到的通信回应消息
char FromSever[100] = {0};
//在一段时间内time持续发送
while (currK < (k + time))
{
oldK = currK;//
Sleep(1000);
memset(FromSever,0,100);
int RecvFlag = recv(socketL, FromSever, 100, 0);
if (RecvFlag == 0)
{
printf("\n<线程 %d>客户端连接已经被服务器切断,误码 %d\n", threadID, WSAGetLastError());
return 1;
}
else if (RecvFlag < 0)
{
printf("\n<线程 %d>客户端接收时出现网络错误, 误码:%d\n", threadID, WSAGetLastError());
}
else
{
cout <<"[" << threadID << "]" << "收到中转站:" << FromSever << endl;
}
currK = GetTickCount();//更新当前运行时间,循环体执行判断
}
}
/***********************************
Description:加载Winsock库
************************************/
BOOL CSOCKET::WSAInit()
{
WSADATA wsaData;
int nRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nRet != 0)
{
return FALSE;
}
return TRUE;
}
/********************************************
Description : 连接服务器端并发送数据
InPut : sockClient - SOCKET
wStr - 日志字符串
Return : TRUE - 执行成功
FALSE - 连接或发送失败
*********************************************/
BOOL CSOCKET::ConnectA(DWO