【转】Winsock开发网络通信程序的经典入门

MFC下CSocket编程详解 MFC下CSocket编程详解: 1. 常用的函数和注意事项(详细的函数接口说明请查看MSDN):    CSocket::Create 初始化(一般写服务器程序都不要用为好,用下面的 CSocket::Socket 初始化)   CSocket::Socket初始化    CSocket::SetSockOpt 设置socket选项    CSocket::Bind 绑定地址 阅读详情

原文:http://www.anqn.com/article/e/2006-01-24/a0977465.shtml

 

对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。

  同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。

  阻塞套接字是指执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的。

  对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步非阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。

  MFC提供了一个异步类CAsyncSocket,它封装了异步、非阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、非阻塞等概念,开发人员无需了解异步、非阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。

  为了简单起见,服务器端和客户端的应用程序均是基于MFC的标准对话框,网络通信部分基于Winsock2 API实现。

  先做服务器端应用程序。

  用MFC向导做一个基于对话框的应用程序SocketSever,注意第三步中不要选上Windwos Sockets选项。在做好工程后,创建一个SeverSock,将它设置为异步非阻塞模式,并为它注册各种网络异步事件,然后与自定义的网络异步事件联系上,最后还要将它设置为监听模式。在自定义的网络异步事件的回调函数中,你可以得到各种网络异步事件,根据它们的类型,做不同的处理。下面将详细介绍如何编写相关代码。

  在SocketSeverDlg.h文件的类定义之前增加如下定义: #define NETWORK_EVENT WM_USER+166 file://定义网络事件

SOCKET ServerSock; file://服务器端Socket


  在类定义中增加如下定义:

class CSocketSeverDlg : CDialog
{
 public:
  SOCKET ClientSock[CLNT_MAX_NUM]; file://存储与客户端通信的Socket的数组

  /*各种网络异步事件的处理函数*/
  void OnClose(SOCKET CurSock); file://对端Socket断开
  void OnSend(SOCKET CurSock); file://发送网络数据包
  void OnReceive(SOCKET CurSock); file://网络数据包到达
  void OnAccept(SOCKET CurSock); file://客户端连接请求

  BOOL InitNetwork(); file://初始化网络函数
  void OnNetEvent(WPARAM wParam, LPARAM lParam); file://异步事件回调函数
  …
};


  在SocketSeverDlg.cpp文件中增加消息映射,其中OnNetEvent是异步事件回调函数名:

ON_MESSAGE(NETWORK_EVENT,OnNetEvent)


  定义初始化网络函数,在SocketSeverDlg.cpp文件的OnInitDialog()中调此函数即可。

BOOL CSocketSeverDlg::InitNetwork()
{
 WSADATA wsaData;

 //初始化TCP协议
 BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
 if(ret != 0)
 {
  MessageBox("初始化网络协议失败!");
  return FALSE;
 }

 //创建服务器端套接字
 ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if(ServerSock == INVALID_SOCKET)
 {
  MessageBox("创建套接字失败!");
  closesocket(ServerSock);
  WSACleanup();
  return FALSE;
 }

 //绑定到本地一个端口上
 sockaddr_in localaddr;
 localaddr.sin_family = AF_INET;
 localaddr.sin_port = htons(8888); //端口号不要与其他应用程序冲突
 localaddr.sin_addr.s_addr = 0;
 if(bind(ServerSock ,(struct sockaddr*)&localaddr,sizeof(sockaddr))= = SOCKET_ERROR)
 {
  MessageBox("绑定地址失败!");
  closesocket(ServerSock);
  WSACleanup();
  return FALSE;
 }

 //将SeverSock设置为异步非阻塞模式,并为它注册各种网络异步事件,其中m_hWnd
 //为应用程序的主对话框或主窗口的句柄
 if(WSAAsyncSelect(ServerSock, m_hWnd, NETWORK_EVENT, FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
 {
  MessageBox("注册网络异步事件失败!");
  WSACleanup();
  return FALSE;
 }
 listen(ServerSock, 5); file://设置侦听模式
 return TRUE;
}

 

下面定义网络异步事件的回调函数

void CSocketSeverDlg::OnNetEvent(WPARAM wParam, LPARAM lParam)
{
 //调用Winsock API函数,得到网络事件类型
 int iEvent = WSAGETSELECTEVENT(lParam);

 //调用Winsock API函数,得到发生此事件的客户端套接字
 SOCKET CurSock= (SOCKET)wParam;

 switch(iEvent)
 {
  case FD_ACCEPT: //客户端连接请求事件
   OnAccept(CurSock);
   break;
  case FD_CLOSE: //客户端断开事件:
   OnClose(CurSock);
   break;
  case FD_READ: //网络数据包到达事件
   OnReceive(CurSock);
   break;
  case FD_WRITE: //发送网络数据事件
   OnSend(CurSock);
   break;
  default: break;
 }
}


  以下是发生在相应Socket上的各种网络异步事件的处理函数,其中OnAccept传进来的参数是服务器端创建的套接字,OnClose()、OnReceive()和OnSend()传进来的参数均是服务器端在接受客户端连接时新创建的用与此客户端通信的Socket。

void CSocketSeverDlg::OnAccept(SOCKET CurSock)
{
 //接受连接请求,并保存与发起连接请求的客户端进行通信Socket
 //为新的socket注册异步事件,注意没有Accept事件
}

void CSocketSeverDlg::OnClose(SOCET CurSock)
{
 //结束与相应的客户端的通信,释放相应资源
}

void CSocketSeverDlg::OnSend(SOCET CurSock)
{
 //在给客户端发数据时做相关预处理
}

void CSocketSeverDlg::OnReceive(SOCET CurSock)
{
 //读出网络缓冲区中的数据包
}


  用同样的方法建立一个客户端应用程序。初始化网络部分,不需要将套接字设置为监听模式。注册异步事件时,没有FD_ACCEPT,但增加了FD_CONNECT事件,因此没有OnAccept()函数,但增加了OnConnect()函数。向服务器发出连接请求时,使用connect()函数,连接成功后,会响应到OnConnect()函数中。下面是OnConnect()函数的定义,传进来的参数是客户端Socket和服务器端发回来的连接是否成功的标志。

void CSocketClntDlg::OnConnect(SOCKET CurSock, int error)
{
 if(0 = = error)
 {
  if(CurSock = = ClntSock)
   MessageBox("连接服务器成功!");
 }
}


  ·定义OnReceive()函数,处理网络数据到达事件;

  ·定义OnSend()函数,处理发送网络数据事件;

  ·定义OnClose()函数,处理服务器的关闭事件。

  以上就是用基于Windows消息机制的异步I/O模型做服务器和客户端应用程序的基本方法。另外还可以用事件模型、重叠模型或完成端口模型,读者可以参考有关书籍。

  在实现了上面的例子后,你将对Winsock编网络通信程序的机制有了一定的了解。接下来你可以进行更精彩的编程, 不仅可以在网上传输普通数据,而且还以传输语音、视频数据,你还可以自己做一个网络资源共享的服务器软件,和你的同学在实验室的局域网里可以共同分享你的成果。

WinSock网络通信程序设计入门 对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。  同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。  阻塞套接字是指执行此套接字的 阅读详情

相关推荐

用WINSOCK实现聊天室的VC++程序设计

用WINSOCK实现聊天室的VC++程序设计 一、SOCKET简介 80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大 学Berkeley分校提供了资金,让他们在UNIX操作系统下实现TCP/IP协 议。在这个项目中,研究人员为TCP/IP网络通信开发了一个API(应用 程序接口)。这个API称为Socket接口(套接字)。今天,SOCKET接口 是TCP/IP网络最为通用的API,

andymei的专栏 5894

MFC的socket

微软的MFC把复杂的WinSock API函数封装到类里,这使得编写网络应用程序更容易。CAsyncSocket类逐个封装了WinSock API,为高级网络程序员 提供了更加有力而灵活的方法。这个类基于程序员了解网络通讯的假设,目的是为了在MFC中使用WinSock,程序员有责任处理诸如阻塞、字节顺序和在Unicode与MBCS 间转换字符的任务。为了给程序员提供更方便的接口以自动处理这些任务,

把握自己。 1万+

MFC实现TCPServer连接多个客户端(附完整源码)

MFC实现TCPServer连接多个客户端(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 790

转: 异步非阻塞套接字Winsock开发网络通信程序的经典入门

转: 异步非阻塞套接字Winsock开发网络通信程序的经典入门 转: 异步非阻塞套接字Winsock开发网络通信程序的经典入门 摘自: http://hi.baidu.com/mcu%5Fspaces/blog/item/aee07a66ed816323ab184cdf.html 对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Syn

junecauzhang的专栏 746

PowerBuilder中实现网络通信的WINSOCK控件使用指南

WINSOCK控件是PowerBuilder编程语言中的一个核心组件,用于实现基于TCP/IP协议的网络通信功能。它提供了一系列的属性、方法和事件,允许开发者在不深入底层网络编程的情况下,轻松创建客户端或服务器端应用程序。通过WINSOCK控件,可以进行数据的发送和接收,以及对网络连接状态进行管理。PowerBuilder提供了许多可选的环境设置,允许开发者根据个人喜好和项目需求进行调整。设置代码格式。

weixin_30600615的博客 689

PB网络通信实践教程:使用winsock.PBL与PSLIB21.DLL

网络通信是现代IT应用中不可或缺的一环,它允许计算机或网络设备之间交换数据。PowerBuilder作为一款快速应用程序开发工具,其网络通信功能主要依赖于Winsock控件,该控件提供了一种在PowerBuilder应用中实现网络功能的方法,如发送和接收数据、建立TCP/IP连接等。winsock.pbl是PowerBuilder中用于网络通信的重要库文件,它利用Windows Sockets API (Winsock) 提供了一套完整的网络通信功能。

weixin_31163455的博客 1023

[转-精]异步非阻塞套接字Winsock开发网络通信程序的经典入门

导读:   关键字 异步非阻塞套接字Winsock开发网络通信程序的经典入门   出处   Winsock开发网络通信程序的经典入门   对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。   同步方式指的是发送方不等接收

613

航空机载总线网络概述

1.机载总线网络概述 现代战斗机的航空电子系统是航空电子技术经历了半个多世纪的漫长演变和不断进步的结果。航空电子系统结构的每次变化,其核心的机载总线网络技术也不断跨上新台阶,而且每次变革都能使飞机性能得到大幅提升。现代飞机的飞行与作战任务包括起飞、巡航、飞行控制、目标搜索、识别跟踪、火控计算、武器投射、制导、电子战、通信等,都需要航空电子系统承担,航空电子系统是现代战斗机的“大脑”和“神经中枢”,机载总线网络则是其关键的“神经网络”。在机载通讯领域发展过程中,具有代表性的典型总线有ARINC429、1553

qq_41854911的博客 1万+

Winsock开发网络通信程序的经典入门

       对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。       同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。    

caiyi9000的专栏 5457

STM32硬件SPI驱动W5500以太网模块全流程(附避坑指南)

本文详细介绍了如何使用STM32硬件SPI驱动W5500以太网模块,包括开发环境准备、SPI接口配置、网络参数设置及常见问题排查。通过官方驱动移植和实战案例,帮助开发者快速实现以太网通信功能,适用于智能家居、工业控制等物联网应用场景。

weixin_29192141的博客 364

手把手教你用Python实现ITRS与GCRS坐标转换(附完整代码)

本文详细介绍了如何使用Python的Astropy库实现ITRS与GCRS坐标转换。文章从环境配置、坐标对象构建入手,深入解析了transform_to方法背后的转换矩阵与地球定向参数管理,并通过卫星地面轨迹计算实战案例,帮助开发者掌握高精度空间坐标转换的核心技术与工程实践。

weixin_28335283的博客 79

VC网络编程-Winsock开发网络通信程序的经典入门

Winsock开发网络通信程序的经典入门对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。   同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接收方发回的响应,才发下

MasterFT的专栏 4144

别再死记硬背了!用TwinCAT 3手把手教你配置EtherCAT伺服驱动的PDO映射(DS402协议)

本文详细介绍了如何使用TwinCAT 3配置EtherCAT伺服驱动的PDO映射(DS402协议),涵盖环境准备、设备扫描、PDO映射实战及高级技巧。通过具体操作步骤和常见问题排查,帮助工程师快速掌握EtherCAT通信配置,提升运动控制系统的效率和稳定性。

weixin_29185493的博客 321

异步非阻塞套接字Winsock开发网络通信程序的经典入门

对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。   同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接

点不着的烟屁 1111

Latex | IEEE双栏排版中长公式的排版

IEEE双栏排版中,有时候公式过于长了,过宽,导致单栏排版不下。

qq_43466146的博客 1万+

基于STM32的工业I/O模块硬件电路实现

深入解析基于STM32的工业I/O模块硬件电路实现,涵盖关键电路设计与信号处理,突出硬件电路稳定性和工业级可靠性,适合嵌入式开发者参考。

weixin_35835018的博客 453

使用WINSOCK的网络通信模拟程序 (客户机端)

使用WINSOCK的网络通信模拟程序 (客户机端) 最近在做嵌入式的project过程中,学习了winsock网络编程,project主要的内容是在移植到stm32之前通过c语言对整个过程进行模拟;过程包括:一台client端的设备和一台作为服务器端的sensor设备通过TCP协议进行连接,通过client端输入不同指令对sensor端进行控制: 例如start命令唤醒sensor; 唤醒后输入任意指令获得sensor端返回的温度数值(此处为随机数生成); 唤醒后输入quit退出连接,结束模拟过程。 下面是

capodexi的博客 1990

linux驱动由浅入深系列:块设备驱动之一(高通eMMC分区实例)

linux驱动由浅入深系列:块设备驱动之一(高通eMMC分区实例)linux驱动由浅入深系列:块设备驱动之二(块设备驱动结构分析)块设备驱动的模型还是基本基于字符设备驱动的,可以简单理解为块设备仅仅增加了操作缓冲区,对用户请求顺序进行队列重拍等等。字符设备驱动的相关分析可以查看本博客相关的博文。 按照本博客的行文习惯,在具体分析块设备驱动代码之前,我们会从整体上了解一下研究对象的特征,以及用户空间...

Radia的专栏 1万+
上一篇: 【转】Windows Mobile中如何建立GPRS连接以便Socket能正常通信
下一篇: 【转】GPRS开发系列文章之入门篇
code09
博客等级 码龄18年 31粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值