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

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
Winsock开发网络通信程序的经典入门

对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(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;
  
defaultbreak;
 }

}

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

相关推荐

VC6 TCP 心跳包程序实战

本文还有配套的精品资源,点击获取 简介:TCP(传输控制协议)是一种可靠的传输层协议,心跳包是保持TCP连接活跃的重要机制。本程序针对VC6Visual C++ 6.0开发环境,帮助初学者理解TCP心跳包的实现原理。程序包含客户端和服务器端源代码,通过实际编码,用户可以掌握Winsock库的使用,实现心跳包发送、接收和异常处理,提升网络编程技能。 1. TCP 心...

weixin_36464343的博客 862

VC6.0编程Socket服务器+客户端)

VC6.0编程Socket服务器+客户端)。非常简单的程序,对初次接触Socket编程的兄弟帮助很大,绝对可以直接使用。

深入理解基于Visual C++的TCP网络通信

套接字(Socket)是一种在计算机网络中实现网络通信的端点。它是一个抽象层,可以让你的程序与另一台计算机上的程序进行数据交换。套接字接口是操作系统提供的网络编程API的一部分,允许进程之间通过网络进行通信。套接字主要分为三种类型:流式套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)。流式套接字提供了面向连接的、可靠的、基于字节流的通信服务,通常使用传输控制协议(TCP)实现。

weixin_33298352的博客 780

VC6.0下的socket编程 实现了UDP数据传输

创建了一个基于socket的UDP传输程序,能够动态输入对方的IP地址和端口号进行数据传输,能够发送数据文件,能够对发送的次数进行计数

基于VCWinSock网络编程实用宝典

Windows Sockets是一套开放的、支持多种协议的Windows下的网络编程接口。现在的Winsock已经基本上实现了与协议无关,你可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。Windows Sockets 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。2、通信完全是异步的…..

m0_59092234的博客 374

vc 网络编程socket

 在网上找了很多的资料,现将这些资料整合起来,详细介绍一下VC下的socket编程,并提供一个服务器客户端具体的实例。希望对您有所帮助 一、原理部分     (个人觉得这篇写的可以,所以转与此,原文地址:http://dev.yesky.com/78/2683078.shtml)  在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型。在这种方案中客户应用程序服务器...

weixin_34149796的博客 313

学用VC++进行Winsock编程──Client端

//////////////////////// 本文来源于网上,出处不详!///////////////////////////////////  说到Winsock,可能很多人还不太了解,但说到OICQ、ICQ、Foxmail、Netants、CuteFTP以及大名鼎鼎的BO2K等等,大家都应该是很熟悉的。如今是网络时代,这些基于网络的软件真的是红红火火!那你有没有想过这些软件是怎么写出来的呢

梦的归宿 5666

VC++ 网络编程

1.七层模型 1)对等层之间不允许直接通信,如两个通信实体的传输层不允许直接通信; 2)上层使用下层提供的服务,如传输层使用网络层的服务; 3)下层向上层提供服务; 4)对等层之间有一个虚拟连接,看起来是直接通信,实际是通过下层来通信,最终的通信是通过物理层的线路完成。 2.OSI各层协议 1)应用层。远程登录协议Telnet、文件传输协议FTP、超文本传输协议HTTP、域名服务DNS、简单邮件传输协议SMTP(发送邮件)、邮局协议POP3(收取邮件)。...

zxf347085420的博客 1210

C/C++网络编程详解(Windows版)

简析一个最简单的服务器和客户端怎么写,以及相关网络函数的常用方法

余识- 3万+

网络编程的一些经典实例

网络编程的一些经典实例 利用CAsyncSocket类实现Socket编程http://www.yesky.com/SoftChannel/72342371928702976/20040521/1800089.shtml 基于VC的串行通信技术应用实例http://www.yesky.com/SoftChannel/72342371928702976/20031013/1735517.shtml

回家念经(kv300)--编程之禅 4318

VC MFC 网络编程入门——简单通信实例学习

VC MFC 网络编程入门——简单通信实例学习2009年12月08日 星期二 下午 09:45<br />对于许多初学者来说,网络通信程序开发,普遍的一个现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。<br />同步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而异步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。<br />阻塞套接字是指执行

1100

vc网络编程入门

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

lanyanjiayu的专栏 699

VC6.0实现socket、tcp传输,支持各类文件

VC6.0实现socket、tcp传输,支持各类文件,本人测试成功的 图片,普通txt文件,其他未测试,但相信可行,代码简单明了

vc6 实现socket服务端客户端

vc6实现大家可以参照

windows编程 VC6.0 网络程序设计 TCP 聊天程序 转发所以发过来的信息 客户端多线程 C语言 客户端与服务器端源代码

windows编程 VC6.0 网络程序设计 TCP 聊天程序 转发所以发过来的信息 客户端多线程 C语言 客户端与服务器端源代码

基于Winsock API的VC网络编程实战

基于Winsock API的VC网络编程实战   随着计算机信息技术的飞速发展,互联网与人类社会的工作、生活越来越紧密相关,它已经成为人类获取、交流信息的重要途径和手段。所以当前对于开发人员来说,网络编程已是必备的技能。本实例详细介绍了如何利用Winsock API编写网络应用程序。  一、实现方法  在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型。在这种方案中客...

weixin_33795806的博客 155
上一篇: English其它-脱口228句
下一篇: VC其它- 在MFC类中各种类的指针的获取和应用
MasterFT
博客等级 码龄20年 48粉丝 59原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值