WSAEventSelect事件Select模型Client——》Server

//////////////////////////////////////////////////
// WSAEventSelect文件

#include <winsock2.h>
#pragma comment(lib, "WS2_32")

class CInitSock
{
public:
CInitSock();
~CInitSock();
};

inline CInitSock::CInitSock()
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 2);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}

inline CInitSock::~CInitSock()
{
::WSACleanup();
}
#include <stdio.h>
#include <iostream.h>
#include <windows.h>

// 初始化Winsock库
CInitSock theSock;
int main1();
int main2();
void main()
{
printf("Please select a item:/n");
printf("s:Server/n");
printf("c:Client/n");
char a;
while(1){
scanf("%c",&a);
if(a=='s'){main1();break;}
else if(a=='c'){main2();break;}
else continue;
}
}
int main1()
{
// 事件句柄和套节字句柄表
WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS];
int nEventTotal = 0;

USHORT nPort = 4567; // 此服务器监听的端口号

// 创建监听套节字
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if(::bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf(" Failed bind() /n");
return -1;
}
::listen(sListen, 5);

// 创建事件对象,并关联到新的套节字
WSAEVENT event = ::WSACreateEvent();
::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE);
// 添加到表中
eventArray[nEventTotal] = event;
sockArray[nEventTotal] = sListen;
nEventTotal++;

// 处理网络事件
while(TRUE)
{
// 在所有事件对象上等待
int nIndex = ::WSAWaitForMultipleEvents(nEventTotal, eventArray, FALSE, WSA_INFINITE, FALSE);
// 对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
nIndex = nIndex - WSA_WAIT_EVENT_0;
for(int i=nIndex; i<nEventTotal; i++)
{
nIndex = ::WSAWaitForMultipleEvents(1, &eventArray[i], TRUE, 1000, FALSE);
if(nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
{
continue;
}
else
{
// 获取到来的通知消息,WSAEnumNetworkEvents函数会自动重置受信事件
WSANETWORKEVENTS event;
::WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event);
if(event.lNetworkEvents & FD_ACCEPT) // 处理FD_ACCEPT通知消息
{
if(event.iErrorCode[FD_ACCEPT_BIT] == 0)
{
if(nEventTotal > WSA_MAXIMUM_WAIT_EVENTS)
{
printf(" Too many connections! /n");
continue;
}
SOCKET sNew = ::accept(sockArray[i], NULL, NULL);
WSAEVENT event = ::WSACreateEvent();
::WSAEventSelect(sNew, event, FD_READ|FD_CLOSE|FD_WRITE);
// 添加到表中
eventArray[nEventTotal] = event;
sockArray[nEventTotal] = sNew;
nEventTotal++;
}
}
else if(event.lNetworkEvents & FD_READ) // 处理FD_READ通知消息
{
if(event.iErrorCode[FD_READ_BIT] == 0)
{
char szText[256];
char temp;
int nRecv = ::recv(sockArray[i], szText, strlen(szText), 0);
if(nRecv > 0)
{
temp=szText[nRecv];
szText[nRecv] = '/0';
printf("接收到数据:%s /n", szText);
szText[nRecv]=temp;
}
}
}
else if(event.lNetworkEvents & FD_CLOSE) // 处理FD_CLOSE通知消息
{
if(event.iErrorCode[FD_CLOSE_BIT] == 0)
{
::closesocket(sockArray[i]);
for(int j=i; j<nEventTotal-1; j++)
{
sockArray[j] = sockArray[j+1];
sockArray[j] = sockArray[j+1];
}
nEventTotal--;
}
}
else if(event.lNetworkEvents & FD_WRITE) // 处理FD_WRITE通知消息
{
}
}
}
}
return 0;
}
//Client
int main2()
{
// 创建套节字
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
printf(" Failed socket() /n");
return 0;
}

// 也可以在这里调用bind函数绑定一个本地地址
// 否则系统将会自动安排

// 填写远程地址信息
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(4567);
// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址
// 如果你的计算机没有联网,直接使用127.0.0.1即可
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
{
printf(" Failed connect() /n");
return 0;
}

char szText[256];
while(TRUE){
scanf("%s",szText);
//puts(szText);
// 向服务器端发送数据
::send(s, szText, strlen(szText), 0);
}
// 关闭套节字
::closesocket(s);

return 0;
}

时间: 2024-09-19 07:27:39

WSAEventSelect事件Select模型Client——》Server的相关文章

EventSelect套接字链表对象和线程链表对象组合下的事件Select模型

WSAEventSelect模型的是事件句柄数组和套节字句柄数组的方式去实现事件Select模型的 接下来用的是套接字链表对象和线程链表对象组合下的事件Select模型   ///////////////////////////////////////////////////// // EventSelect.h文件 DWORD WINAPI ServerThread(LPVOID lpParam); // 套节字对象 typedef struct _SOCKET_OBJ { SOCKET s;

select模型Client——》Server

////////////////////////////////////////////////////// // select.cpp文件 #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib class CInitSock { public: CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)

socket异步通信-c++ 异步通信 event select模型

问题描述 c++ 异步通信 event select模型 怎么触发 FD_WRIEE 这个网络事件 我在网上搜了很多 都不是很明白 最好能提供触发的代码 望不啬指教 解决方案 问题已解决 我总结一下吧一直搞不懂 WSAEventSelect 的 FD_WRITE ,不知道怎么利用他在自己想发数据的时候发数据,后来知道了想发随时发消息 要自己另外去写send方法,FD_WRITE 是用于一开始连接成功侯就开始发送大批量数据的,比如发一个视频连接给别人 ,别人接了 那么这个时候就触发了FD_WRIT

Java 在Client/Server 网络中的应用 (转)

client|server|网络 Java 在Client/Server 网络中的应用 (作者: 2000年08月09日 10:19) 随着Java语言的日益流行,特别是Java与Internet Web的密切结合,使它在全球取得了巨大的成功.Java语言以其独立于平台.面向对象.分布式.多线索及完善的安全机制等特色,成为现代信息系统建设中的良好的开发平台和运行环境. 一.Java网络应用模型 和Internet上的许多环境一样,完整的Java应用环境实际上也是一个客户机/服务器环境,更确切地说

用vfp与sql server构建Client/Server应用程序(SPT)(1)

一些题外话 最近有一种好的现象--越来越多的Visual FoxPro用户开始注意到Client/Server应用程序的重要性,他们开始安装SQL Server了.作为开发人员,我们没有必要深入认识SQL Server的种种(我个人以为那是数据库管理员-DBA的事情),我们要解决的是怎样使Visual FoxPro与SQL Server在一起顺利的运行,怎样发挥两者的优越特性. "远程视图"一章已经涉及到了许多深层次的问题,但遗憾的是(可能是文章太过枯燥)很少有人关注它!笔者到现在还是

用vfp与sql server构建Client/Server应用程序(远程视图)(4)

缓冲(Buffering) Visual FoxPro 中的缓冲技术 当远端数据下载到客户端时,这些数据就被压入缓冲之中.在客户端用户对数据的各种移动并不反映到数据源,而是在用户确认对数据的变动后,才把各种变动以SQL描述的形式发送到后端.那么为什么不让Visual FoxPro直接一步一动的操控远程数据,就像在不使用缓冲技术控制Visual FoxPro本地数据那样.我想原因在于: 在 Client/Server 构架的应用中,数据库服务器需要同时处理许多客户的请求,如果有一个客户"直接&qu

用vfp与sql server构建Client/Server应用程序(远程视图)(2)

通过工具建立连接 以上我们都是通过命令的方式建立连接,现在我们将使用Visual FoxPro提供的连接设计器建立连接.上文我们讲到:连接对象分为两类:"基于 DSN 的连接对象"和"基于字符串的连接对象".图5: 在连接设计器中选择"数据源.用户标识.密码"就说明在建立"基于 DSN 的连接对象",在"数据源"列表框中可选择当前可用的用户型.系统型 DSN. 在连接设计器中选择"连接串"

用vfp与sql server构建Client/Server应用程序(远程视图)(1)

本文是<用 Visual FoxPro 与 SQL Server 构建 Client/Server 应用程序>系列的一部分,照例"远程视图"应不是开篇章节,但我们发现:在我们为网站准备的文章中有太多的理论性的东西,为了缓解这一矛盾,我们决定把"远程视图"提上来先写. 当下最流行的 ADO 脱胎于 Visual FoxPro,在实际使用中两者各有特色,所以不要小看 Visual FoxPro 在远程数据处理上的能力,它绝对强大!读者可以参看本站的<M

C++中I/O模型之select模型实例_C 语言

本文实例讲述了C++中I/O模型的select模型用法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: void main()  {      CInitSock initSock;      USHORT nPort = 9999; //监听的端口      SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      if (sListen == INVALID_SOCKET)      {