整个工程的源码下载地址为
http://download.csdn.net/detail/u012607841/9158527
发送数据测试
.版本 2
.程序集 窗口程序集1
.子程序 __启动窗口_创建完毕
.子程序 _按钮1_被单击
客户1.发送数据 (#常量1)
.子程序 _客户1_数据到达
编辑框1.内容 = 到文本 (客户1.取回数据 ())
标签1.标题 = “文本长度 ” + 到文本 (取文本长度 (编辑框1.内容))
.子程序 _按钮2_被单击
.局部变量 是否成功, 逻辑型
是否成功 = 客户1.连接 (“127.0.0.1”, 8080)
_启动窗口.标题 = 选择 (是否成功, “链接成功”, “链接失败”)
.子程序 __启动窗口_将被销毁
客户1.断开连接 ()
基础类模块源码
#ifndef socket_h__
#define socket_h__
#include <WinSock2.h>
#include <string>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
DWORD WINAPI OnRecvThread(LPVOID lpvoid);
class CBuffer
{
public:
CBuffer()
{
}
CBuffer(const CBuffer& buf): m_Data(buf.m_Data)
{
}
~CBuffer()
{
}
VOID AddData(VOID* pData,DWORD nSize)
{
string data;
data.resize(nSize,0);
CopyMemory((VOID*)data.data(),pData,nSize);
m_Data += data;
}
CBuffer& operator+=(const char* pText)
{
m_Data+=pText;
return*this;
}
CBuffer& operator+=(const CBuffer& buf)
{
m_Data+=buf.m_Data;
return*this;
}
VOID* GetData()
{
return (VOID*)m_Data.data();
}
DWORD GetSize()
{
return m_Data.size();
}
private:
string m_Data;
};
class CAccept
{
public:
CAccept()
{
}
CAccept(SOCKET s,SOCKADDR_IN ar)
{
m_addr = ar;
m_sAccept = s;
}
char* GetIP()
{
return inet_ntoa(m_addr.sin_addr);
}
int Recv(char* buf,int len)
{
return ::recv(m_sAccept,buf,len,0);
}
int Send(char* buf,int len)
{
return ::send(m_sAccept,buf,len,0);
}
SOCKET GetSocket()
{
return m_sAccept;
}
private:
SOCKET m_sAccept;
SOCKADDR_IN m_addr;
};
int RecvData(CAccept* pAcp,CBuffer& buf);
int SendData(CAccept* pAcp,CBuffer& buf);
class CSocket
{
public:
CSocket()
{
WORD wVersionRequested;
WSADATA wsaData; // 这结构是用于接收Wjndows Socket的结构信息的
wVersionRequested = MAKEWORD( 2, 2 ); // 请求1.1版本的WinSock库
int err = WSAStartup( wVersionRequested, &wsaData );
}
~CSocket()
{
closesocket(sockfd);
WSACleanup();
}
bool socket_TCP()
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
return (INVALID_SOCKET != sockfd);
}
bool Bind(u_short uPort)
{
/* setting server's socket */
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET; // IPv4 network protocol
server_addr.sin_port = htons(uPort);
server_addr.sin_addr.s_addr = INADDR_ANY; // auto IP detect
memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
return (::bind(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) != SOCKET_ERROR);
}
bool Listen()
{
return(::listen(sockfd, SOMAXCONN) != SOCKET_ERROR);
}
CAccept Accept()
{
SOCKADDR_IN client_addr;
int addr_size = sizeof(struct sockaddr_in);
SOCKET client_fd = ::accept(sockfd, (struct sockaddr *)&client_addr, &addr_size);
CAccept acp(client_fd,client_addr);
return acp;
}
int setsockopt(int optname,const char* optval,int optlen)
{
int level = SOL_SOCKET; //原始套接字
return ::setsockopt(sockfd,level,optname,optval,optlen);
}
private:
SOCKET sockfd;
};
class CClientBase
{
public:
CClientBase()
{
}
virtual bool InitServer(unsigned short uPort)
{
m_sock.socket_TCP();
m_sock.Bind(uPort);
m_sock.Listen();
return true;
}
virtual VOID _OnRun()
{
}
VOID Run()
{
m_bRun = TRUE;
DWORD dwThreadId = 0;
m_hThread = CreateThread(NULL,NULL,OnRecvThread,(VOID*)this,0,&dwThreadId);
WaitForSingleObject(m_hThread,INFINITE);
}
VOID Stop()
{
m_bRun = FALSE;
}
protected:
CSocket m_sock;
SOCKET sockfd;
SOCKET client_fd;
HANDLE m_hThread;
bool m_bRun;
};
#endif // socket_h__
这个是Select模型
#ifndef DemoSelect_h__
#define DemoSelect_h__
DWORD WINAPI WorkerThread(LPVOID lpParam);
class CClientSelect : public CClientBase
{
public:
CClientSelect()
{
}
VOID Worker()
{
int i;
fd_set fdread;
int ret;
struct timeval tv = {1, 0};
char szMessage[MAX_PATH];
while (m_bRun)
{
FD_ZERO(&fdread);
for (i = 0; i < g_iTotalConn; i++)
{
FD_SET(g_CliSocketArr[i].GetSocket(), &fdread);
}
// We only care read event
ret = select(0, &fdread, NULL, NULL, &tv);
if (ret == 0)
{
// Time expired
printf("超时!\r\n");
continue;
}
for (i = 0; i < g_iTotalConn; i++)
{
SOCKET sock = g_CliSocketArr[i].GetSocket();
if (FD_ISSET(sock, &fdread))
{
// A read event happened on g_CliSocketArr[i]
ret = recv(sock, szMessage, MAX_PATH, 0);
if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
{
// Client socket closed
printf("Client socket %d closed.\r\n", g_CliSocketArr[i].GetIP());
closesocket(sock);
if (i < g_iTotalConn - 1)
{
g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];
}
}
else
{
// We received a message from client
szMessage[ret] = '\0';
send(sock, szMessage, strlen(szMessage), 0);
}
}
}
}
}
virtual VOID _OnRun()
{
DWORD dwThreadId;
HANDLE hThread = CreateThread(NULL, 0, WorkerThread, this, 0, &dwThreadId);
g_iTotalConn = 0;
while (TRUE)
{
CAccept acp = m_sock.Accept();
// Accept a connection
printf("Accepted client:%s:\r\n",acp.GetIP());
// Add socket to g_CliSocketArr
g_CliSocketArr[g_iTotalConn++] = acp;
}
WaitForSingleObject(hThread,INFINITE);
}
private:
int g_iTotalConn ;
CAccept g_CliSocketArr[FD_SETSIZE];
};
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
CClientSelect* pSelect = (CClientSelect*)lpParam;
pSelect->Worker();
return 0;
}
#endif // DemoSelect_h__
event模型
#ifndef DemoEvents_h__
#define DemoEvents_h__
DWORD WINAPI EventsWorkerThread(LPVOID lpParam);
class CClientEvents : public CClientBase
{
public:
CClientEvents()
{
}
VOID Worker()
{
int ret, index;
WSANETWORKEVENTS NetworkEvents;
char szMessage[MAX_PATH];
while (TRUE)
{
ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE);
if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT)
{
continue;
}
index = ret - WSA_WAIT_EVENT_0;
WSAEnumNetworkEvents(g_CliSocketArr[index].GetSocket(), g_CliEventArr[index], &NetworkEvents);
if (NetworkEvents.lNetworkEvents & FD_READ)
{
// Receive message from client
ret = recv(g_CliSocketArr[index].GetSocket(), szMessage, MAX_PATH, 0);
if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
{
Cleanup(index);
}
else
{
szMessage[ret] = '\0';
send(g_CliSocketArr[index].GetSocket(), szMessage, strlen(szMessage), 0);
}
}
if (NetworkEvents.lNetworkEvents & FD_CLOSE)
{
Cleanup(index);
}
}
}
virtual VOID _OnRun()
{
DWORD dwThreadId;
HANDLE hThread = CreateThread(NULL, 0, EventsWorkerThread, this, 0, &dwThreadId);
g_iTotalConn = 0;
while (TRUE)
{
CAccept acp = m_sock.Accept();
// Accept a connection
printf("Accepted client:%s:\r\n",acp.GetIP());
// Associate socket with network event
g_CliSocketArr[g_iTotalConn++] = acp;
g_CliEventArr[g_iTotalConn] = WSACreateEvent();
WSAEventSelect(
g_CliSocketArr[g_iTotalConn].GetSocket(),
g_CliEventArr[g_iTotalConn],
FD_READ | FD_CLOSE);
g_iTotalConn++;
}
WaitForSingleObject(hThread,INFINITE);
}
void Cleanup(int index)
{
closesocket(g_CliSocketArr[index].GetSocket());
WSACloseEvent(g_CliEventArr[index]);
if (index < g_iTotalConn - 1)
{
g_CliSocketArr[index] = g_CliSocketArr[g_iTotalConn - 1];
g_CliEventArr[index] = g_CliEventArr[g_iTotalConn - 1];
}
g_iTotalConn--;
}
private:
int g_iTotalConn ;
CAccept g_CliSocketArr[FD_SETSIZE];
WSAEVENT g_CliEventArr[MAXIMUM_WAIT_OBJECTS];
};
DWORD WINAPI EventsWorkerThread(LPVOID lpParam)
{
CClientSelect* pSelect = (CClientSelect*)lpParam;
pSelect->Worker();
return 0;
}
#endif // DemoEvents_h__
调用代码
#include "stdafx.h"
#include "DemoHttpServer.h"
#include "DemoSelect.h"
#include "DemoEvents.h"
void testDemoHttpServer()
{
CClientHTTPServer Client;
Client.InitServer(8080);
Client.Run();
}
void testDemoSelect()
{
CClientSelect Client;
Client.InitServer(8080);
Client.Run();
}
void testDemoEvent()
{
CClientEvents Client;
Client.InitServer(8080);
Client.Run();
}
int main(char argc, char *argv[])
{
testDemoEvent();
return 0;
}