vc网络编程经典案例
‘壹’ 求推荐一本 VC++网络编程 的好书
Windows网络与通信程序设计(第2版)王艳平这本书写的非常好,我有本王艳平写的windows程序设计,写得很好,我自己不做网络开发,就没有买网络的那本书!不过推荐你看看,真的很不错!
本书将编程方法、网络协议和应用实例有机结合起来,详细阐明Windows网络编程的各方面内容。本书首先介绍Windows平台上进行网络编程的基础知识,包括网络硬件、术语、协议、Winsock编程接口和各种I/O方法等;然后通过具体实例详细讲述当前流行的高性能可伸缩服务器设计、IP多播和Internet广播、P2P程序设计、原始套接字、SPI、协议驱动的开发和原始以太数据的发送、ARP欺骗技术、LAN和WAN上的扫描和侦测技术、个人防火墙与网络封包截获技术等;最后讲述IP帮助函数和E-mail的开发方法。本书结构紧凑,内容由浅入...
第1章计算机网络基础1
1.1网络的概念和网络的组成1
1.2计算机网络参考模型2
1.2.1协议层次2
1.2.2TCP/IP参考模型2
1.2.3应用层(ApplicationLayer)3
1.2.4传输层(TransportLayer)3
1.2.5网络层(NetworkLayer)3
1.2.6链路层(LinkLayer)4
1.2.7物理层(PhysicalLayer)4
1.3网络程序寻址方式4
1.3.1MAC地址4
1.3.2IP地址5
1.3.3子网寻址6
1.3.4端口号8
1.3.5网络地址转换(NAT)8
1.4网络应用程序设计基础10
1.4.1网络程序体系结构10
1.4.2网络程序通信实体11
1.4.3网络程序开发环境12
第2章Winsock编程接口13
2.1Winsock库13
2.1.1Winsock库的装入和释放13
2.1.2封装CInitSock类14
2.2Winsock的寻址方式和字节顺序14
2.2.1Winsock寻址14
2.2.2字节顺序16
2.2.3获取地址信息17
2.3Winsock编程详解20
2.3.1Winsock编程流程20
2.3.2典型过程图23
2.3.3TCP服务器和客户端程序举例24
2.3.4UDP编程26
2.4网络对时程序实例28
2.4.1时间协议(TimeProtocol)28
2.4.2TCP/IP实现代码29
第3章Windows套接字I/O模型31
3.1套接字模式31
3.1.1阻塞模式31
3.1.2非阻塞模式31
3.2选择(select)模型32
3.2.1select函数32
3.2.2应用举例33
3.3WSAAsyncSelect模型36
3.3.1消息通知和WSAAsyncSelect函数36
3.3.2应用举例37
3.4WSAEventSelect模型40
3.4.1WSAEventSelect函数40
3.4.2应用举例42
3.4.3基于WSAEventSelect模型的服务器设计44
3.5重叠(Overlapped)I/O模型53
3.5.1重叠I/O函数53
3.5.2事件通知方式56
3.5.3基于重叠I/O模型的服务器设计56
第4章IOCP与可伸缩网络程序67
4.1完成端口I/O模型67
4.1.1什么是完成端口(completionport)对象67
4.1.2使用IOCP的方法67
4.1.3示例程序69
4.1.4恰当地关闭IOCP72
4.2Microsoft扩展函数72
4.2.1GetAcceptExSockaddrs函数73
4.2.2TransmitFile函数73
4.2.3TransmitPackets函数74
4.2.4ConnectEx函数75
4.2.5DisconnectEx函数76
4.3可伸缩服务器设计注意事项76
4.3.1内存资源管理76
4.3.2接受连接的方法77
4.3.3恶意客户连接问题77
4.3.4包重新排序问题78
4.4可伸缩服务器系统设计实例78
4.4.1CIOCPServer类的总体结构78
4.4.2数据结构定义和内存池方案82
4.4.3自定义帮助函数85
4.4.4开启服务和停止服务88
4.4.5I/O处理线程93
4.4.6用户接口和测试程序99
第5章互联网广播和IP多播100
5.1套接字选项和I/O控制命令100
5.1.1套接字选项100
5.1.2I/O控制命令102
5.2广播通信103
5.3IP多播(Multicasting)105
5.3.1多播地址105
5.3.2组管理协议(IGMP)105
5.3.3使用IP多播106
5.4基于IP多播的组讨论会实例110
5.4.1定义组讨论会协议110
5.4.2线程通信机制111
5.4.3封装CGroupTalk类111
5.4.4程序界面117
第6章原始套接字121
6.1使用原始套接字121
6.2ICMP编程121
6.2.1ICMP与校验和的计算121
6.2.2Ping程序实例124
6.2.3路由跟踪126
6.3使用IP头包含选项129
6.3.1IP数据报格式129
6.3.2UDP数据报格式131
6.3.3原始UDP封包发送实例133
6.4网络嗅探器开发实例134
6.4.1嗅探器设计原理135
6.4.2网络嗅探器的具体实现136
6.4.3侦听局域网内的密码138
6.5TCP通信开发实例140
6.5.1创建一个原始套接字,并设置IP头选项140
6.5.2构造IP头和TCP头140
6.5.3发送原始套接字数据报142
6.5.4接收数据146
第7章Winsock服务提供者接口(SPI)147
7.1SPI概述147
7.2Winsock协议目录148
7.2.1协议特性149
7.2.2使用WinsockAPI函数枚举协议150
7.2.3使用WinsockSPI函数枚举协议151
7.3分层服务提供者(LSP)153
7.3.1运行原理153
7.3.2安装LSP154
7.3.3移除LSP158
7.3.4编写LSP159
7.3.5LSP实例161
7.4基于SPI的数据报过滤实例165
7.5基于Winsock的网络聊天室开发171
7.5.1服务端171
7.5.2客户端171
7.5.3聊天室程序的设计说明172
7.5.4核心代码分析172
第8章Windows网络驱动接口标准(NDIS)和协议驱动的开发176
8.1核心层网络驱动176
8.1.1Windows2000及其后产品的网络体系结构176
8.1.2NDIS网络驱动程序177
8.1.3网络驱动开发环境178
8.2WDM驱动开发基础181
8.2.1UNICODE字符串181
8.2.2设备对象181
8.2.3驱动程序的基本结构183
8.2.4I/O请求包(I/Orequestpacket,IRP)和I/O堆栈183
8.2.5完整驱动程序示例186
8.2.6扩展派遣接口188
8.2.7应用举例(进程诊测实例)191
8.3开发NDIS网络驱动预备知识198
8.3.1中断请求级别(InterruptRequestLevel,IRQL)198
8.3.2旋转锁(SpinLock)198
8.3.3双链表199
8.3.4封包结构199
8.4NDIS协议驱动200
8.4.1注册协议驱动200
8.4.2打开下层协议驱动的适配器201
8.4.3协议驱动的封包管理202
8.4.4在协议驱动中接收数据203
8.4.5从协议驱动发送封包204
8.5NDIS协议驱动开发实例204
8.5.1总体设计204
8.5.2NDIS协议驱动的初始化、注册和卸载206
8.5.3下层NIC的绑定和解除绑定209
8.5.4发送数据217
8.5.5接收数据219
8.5.6用户IOCTL处理225
第9章网络扫描与检测技术233
9.1网络扫描基础知识233
9.1.1以太网数据帧233
9.1.2ARP234
9.1.3ARP格式236
9.1.4SendARP函数237
9.2原始以太封包的发送238
9.2.1安装协议驱动238
9.2.2协议驱动用户接口238
9.2.3发送以太封包的测试程序244
9.3局域网计算机扫描245
9.3.1管理原始ARP封包246
9.3.2ARP扫描示例249
9.4互联网计算机扫描253
9.4.1端口扫描原理253
9.4.2半开端口扫描实现254
9.5ARP欺骗原理与实现259
9.5.1IP欺骗的用途和实现原理259
9.5.2IP地址冲突260
9.5.3ARP欺骗示例261
第10章点对点(P2P)网络通信技术264
10.1P2P穿越概述264
10.2一般概念265
10.2.1NAT术语265
10.2.2中转265
10.2.3反向连接266
10.3UDP打洞267
10.3.1中心服务器267
10.3.2建立点对点会话267
10.3.3公共NAT后面的节点267
10.3.4不同NAT后面的节点268
10.3.5多级NAT后面的节点269
10.3.6UDP空闲超时270
10.4TCP打洞271
10.4.1套接字和TCP端口重用271
10.4.2打开点对点的TCP流271
10.4.3应用程序看到的行为272
10.4.4同步TCP打开273
10.5Internet点对点通信实例273
10.5.1总体设计273
10.5.2定义P2P通信协议274
10.5.3客户方程序275
10.5.4服务器方程序287
10.5.5测试程序291
第11章核心层网络封包截获技术294
11.1Windows网络数据和封包过滤概述294
11.1.1Windows网络系统体系结构图294
11.1.2用户模式下的网络数据过滤295
11.1.3内核模式下的网络数据过滤296
11.2中间层网络驱动PassThru296
11.2.1PassThruNDIS中间层驱动简介296
11.2.2编译和安装PassThru驱动297
11.3扩展PassThruNDISIM驱动——添加IOCTL接口297
11.3.1扩展之后的PassThru驱动(PassThruEx)概况297
11.3.2添加基本的DeviceIoControl接口298
11.3.3添加绑定枚举功能302
11.3.4添加ADAPT结构的引用计数307
11.3.5适配器句柄的打开/关闭函数308
11.3.6句柄事件通知315
11.3.7查询和设置适配器的OID信息315
11.4扩展PassThruNDISIM驱动——添加过滤规则323
11.4.1需要考虑的事项323
11.4.2过滤相关的数据结构324
11.4.3过滤列表326
11.4.4网络活动状态327
11.4.5IOCTL控制代码328
11.4.6过滤数据331
11.5核心层过滤实例339
第12章Windows网络防火墙开发技术342
12.1防火墙技术概述342
12.2金羽(Phoenix)个人防火墙浅析343
12.2.1金羽(Phoenix)个人防火墙简介343
12.2.2金羽(Phoenix)个人防火墙总体设计344
12.2.3金羽(Phoenix)个人防火墙总体结构345
12.3开发前的准备345
12.3.1常量的定义346
12.3.2访问规则348
12.3.3会话结构348
12.3.4文件结构349
12.3.5UNICODE支持355
12.4应用层DLL模块356
12.4.1DLL工程框架356
12.4.2共享数据和IO控制362
12.4.3访问控制列表ACL(AccessList)364
12.4.4查找应用程序访问权限的过程367
12.4.5类的接口——检查函数370
12.5核心层SYS模块373
12.6主模块工程375
12.6.1I/O控制类375
12.6.2主应用程序类377
12.6.3主对话框中的属性页380
12.6.4主窗口类381
12.7防火墙页面383
12.7.1网络访问监视页面383
12.7.2应用层过滤规则页面387
12.7.3核心层过滤规则页面397
12.7.4系统设置页面403
第13章IP帮助函数406
13.1IP配置信息406
13.1.1获取网络配置信息406
13.1.2管理网络接口408
13.1.3管理IP地址412
13.2获取网络状态信息415
13.2.1获取TCP连接表415
13.2.2获取UDP监听表418
13.2.3获取IP统计数据420
13.3路由管理427
13.3.1获取路由表427
13.3.2管理特定路由431
13.3.3修改默认网关的例子432
13.4ARP表管理433
13.4.1获取ARP表433
13.4.2添加ARP入口434
13.4.3删除ARP入口434
13.4.4打印ARP表的例子434
13.5进程网络活动监视实例438
13.5.1获取通信的进程终端438
13.5.2Netstate源程序代码439
第14章Email协议及其编程444
14.1概述444
14.2电子邮件介绍445
14.2.1电子邮件Internet的地址445
14.2.2Internet邮件系统445
14.2.3电子邮件信头的结构及分析446
14.3SMTP原理448
14.3.1SMTP原理分析448
14.3.2SMTP工作机制449
14.3.3SMTP命令码和工作原理449
14.3.4SMTP通信模型450
14.3.5SMTP的命令和应答451
14.4POP3协议原理452
14.4.1POP3协议简介452
14.4.2POP3工作原理453
14.4.3POP3命令原始码454
14.4.4POP3会话实例459
14.5实例分析与程序设计460
14.5.1总界面设计460
14.5.2SMTP客户端设计461
14.5.3POP3客户端设计473
‘贰’ socket VC++ 编程 的比较经典的着作
VC对SOCKET编程提供的支持并不是特别丰富,
主要是MFC中的CAsyncSocket、CSocket,所以着作不多。
但是,Windows API 对SOCKET支持就丰富多了,MFC的那两个类也是基于
WinSOCK的异步选择模型。着作也有很多。推荐你一本:
<<Windows 网络编程技术>>
这本书里的知识要是消化掌握了,那你就足以应付多数Windows环境下的网络开发了。
我认为本书的重点章节是
第7章,winsock 基础
第8章,winsock I/O 方法
这两章掌握了,编写网络模块就不成问题了。
‘叁’ vc最简单的 网络编程如何在一台电脑测试
利用回送IP:127.0.0.1 开两个程序,一个server,一个client
如MSDN实例:
client端:
#include <stdio.h>
#include "winsock2.h"
void main() {
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// Create a socket.
SOCKET m_socket;
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// Connect to a server.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( 27015 );
if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
printf( "Failed to connect.\n" );
WSACleanup();
return;
}
// Send and receive data.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[32] = "Client: Sending data.";
char recvbuf[32] = "";
bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
printf( "Bytes Sent: %ld\n", bytesSent );
while( bytesRecv == SOCKET_ERROR ) {
bytesRecv = recv( m_socket, recvbuf, 32, 0 );
if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {
printf( "Connection Closed.\n");
break;
}
if (bytesRecv < 0)
return;
printf( "Bytes Recv: %ld\n", bytesRecv );
}
return;
}
server端:
#include <stdio.h>
#include "winsock2.h"
void main() {
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// Create a socket.
SOCKET m_socket;
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// Bind the socket.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
service.sin_port = htons( 27015 );
if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf( "bind() failed.\n" );
closesocket(m_socket);
return;
}
// Listen on the socket.
if ( listen( m_socket, 1 ) == SOCKET_ERROR )
printf( "Error listening on socket.\n");
// Accept connections.
SOCKET AcceptSocket;
printf( "Waiting for a client to connect...\n" );
while (1) {
AcceptSocket = SOCKET_ERROR;
while ( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( m_socket, NULL, NULL );
}
printf( "Client Connected.\n");
m_socket = AcceptSocket;
break;
}
// Send and receive data.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[32] = "Server: Sending Data.";
char recvbuf[32] = "";
bytesRecv = recv( m_socket, recvbuf, 32, 0 );
printf( "Bytes Recv: %ld\n", bytesRecv );
bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
printf( "Bytes Sent: %ld\n", bytesSent );
return;
}
‘肆’ 求一个C++多线程通信的例子
关于winsock服务器和客户端编程2008年12月28日 星期日 23:22在网络编程中,最常用和最基础的就是WINSOCK. 现在我们讨论WINDOWS下的SOCKET编程.
大凡在WIN32平台上的WINSOCK编程都要经过下列步骤:
定义变量->获得WINDOCK版本->加载WINSOCK库->初始化->创建套接字->设置套接字选项->关闭套接字->卸载WINSOCK库->释放资源
下面介绍WINSOCK C/S的建立过程:
服务器 客户端
________________________________________________
1 初始化WSA 1 初始化WSA
____________________________________________________
2 建立一个SOCKET 2 建立一个SOCKET
_____________________________________________________
3 绑定SOCKET 3 连接到服务器
_____________________________________________________
4 在指定的端口监听 4 发送和接受数据
_____________________________________________________
5 接受一个连接 5 断开连接
______________________________________________________-
6 发送和接受数据
___________________________________________________
7 断开连接
__________________________________________________
大家注意,在VC中进行WINSOCK编程时,需要引入如下两个库文件:WINSOCK.H(这个是WINSOCK API的头文件,WIN2K以上支持WINSOCK2,所以
可以用WINSOCK2.H);Ws2_32.lib(WINSOCK API连接库文件).
使用方式如下:
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
下面我们通过具体的代码演示服务器和客户端的工作流程:
首先,建立一个WSADATA结构,通常用wsaData
WSADATA wsaData;
然后,调用WSAStartup函数,这个函数是连接应用程序与winsock.dll的第一个调用.其中,第一个参数是WINSOCK 版本号,第二个参数是指向
WSADATA的指针.该函数返回一个INT型值,通过检查这个值来确定初始化是否成功.调用格式如下:WSAStartup(MAKEWORD(2,2),&wsaData),其中
MAKEWORD(2,2)表示使用WINSOCK2版本.wsaData用来存储系统传回的关于WINSOCK的资料.
if(iResuit=WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("WSAStartup failed:%d",GetLastError()); //返回值不等与0,说明初始化失败
ExitProcess(); //退出程序
}
应用程序在完成对请求的SOCKET库使用后,要调用WSACleanup函数来接触SOCKET库的绑定,并且释放资源.
注意WSAStartup初始化后,必须建立一个SOCKET结构来保存SOCKET句柄.
下面我们建立一个SOCKET.
首先我们建立一个m_socket的SOCKET句柄,接着调用socket()函数,函数返回值保存在m_socket中.我们使用AF_INFE,SOCK_STREAM,IPPROTO_TCP
三个参数.第一个表示地址族,AF_INFE表示TCP/IP族,第二个表示服务类型,在WINSOCK2中,SOCKET支持以下三种类型;
SOCK_STREAM 流式套接字
SOCK_DGRAM 数据报套接字
SOCK_RAW 原始套接字
第三个参数表示协议:
IPPROTO_UDP UDP协议 用于无连接数据报套接字
IPPROTO_TCP TCP协议 用于流式套接字
IPPROTO_ICMP ICMP协议用于原始套接字
m_socket=socket(AF_INFE,SOCK_STREAM,IPPROTO_TCP); //创建TCP协议
以下代码用于检查返回值是否有错误:
if(m_scoket==INVALID_SOCKET)
{
prinrf("Error at socket():%d\n",GetLastError());
WSACleanup(); //释放资源
return;
}
说明,如果socket()调用失败,他将返回INVALID_SOCKET.
为了服务器能接受一个连接,他必须绑定一个网络地址,下面的代码展示如何绑定一个已经初始化的IP和端口的Socket.客户端程序用这个
IP地址和端口来连接服务器.
sockaddr_in service;
service.sin_family=AF_INET; //INTERNET地址族
service.sin_addr.s_addr=inet_addr("127.0.0.1"); //将要绑定的本地IP地址
service.sin_port=htons(27015); //27015将要绑定的端口
下面我们调用BIND函数,把SOCKET和SOCKADDR以参数的形式传入,并检查错误.
if(bind(m_socket,(SOCKADDR*)&SERVICE,sizeof(service))==SOCKET_ERROR)
{
printf("bind() failed.\n");
closesocket(m_socket);
return;
}
当绑定完成后,服务器必须建立一个监听队列,以接受客户端的请求.listen()使服务器进入监听状态,该函数调用成功返回0,否则返回
SOCKET_ERROR.代码如下:
if(listen(m_socket,1)==SOCKET-ERROR)
{
printf("error listening on socket.\n");
}
服务器端调用完LISTEN()后,如果此时客户端调用CONNECT()函数,服务器端必须在调用ACCEPT().这样服务器和客户端才算正式完成通信程序的
连接动作.
一旦服务器开始监听,我们就要指定一个句柄来表示利用ACCEPT()函数接受的连接,这个句柄是用来发送和接受数据的表示.建立一个SOCKET句柄
Socket AcceptSocket 然后利用无限循环来检测是否有连接传入.一但有连接请求,ACCEPT()函数就会被调用,并且返回这次连接的句柄.
printf("waitong for a client to connect...\n");
while(1)
{
AcceptSocket=SOCKET_ERROR;
while(AcceptSocket==SOCKET_ERROR)
{
AcceptSocket=accept(m_socket,NULL,NULL);
}
}
下面看客户端端代码:
sockaddr_in clientService;
clientService.sin_family=AF_INET; //INTERNET地址族
clientService.sin_addr.s_addr=inet_addr("127.0.0.1"); //将要绑定的本地IP地址
clientService.sin_port=htons(27015); //27015将要绑定的端口
下面调用CONNECT()函数:
if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
{
printf( "Failed to connect.\n" );
WSACleanup();
return;
} //如果调用失败清理退出
//调用成功继续读写数据
_________________________________________________________________________________________________
到这里,服务器和客户端的基本流程介绍完毕,下面我们介绍数据交换.
send():
int send
{
SOCKET s, //指定发送端套接字
const char FAR?*buf, //指明一个存放应用程序要发送的数据的缓冲区
int len, //实际要发送的数据字节数
int flags //一般设置为0
};
C/S都用SEND函数向TCP连接的另一端发送数据.
recv():
int recv
{
SOCKET s, //指定发送端套接字
char FAR?*buf, //指明一个缓冲区 存放RECC受到的数据
int len, //指明BUF的长度
int flags //一般设置为0
};
C/S都使用RECV函数从TCP连接的另一端接受数据
下面将完整的程序代码提供如下,大家可直接编译运行
首先看客户端的代码:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void main() {
// 初始化 Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// 建立socket socket.
SOCKET client;
client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( client == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// 连接到服务器.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( 27015 );
if ( connect( client, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
printf( "Failed to connect.\n" );
WSACleanup();
return;
}
// 发送并接收数据.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[32] = "Client: Sending data.";
char recvbuf[32] = "";
bytesSent = send( client, sendbuf, strlen(sendbuf), 0 );
printf( "Bytes Sent: %ld\n", bytesSent );
while( bytesRecv == SOCKET_ERROR ) {
bytesRecv = recv( client, recvbuf, 32, 0 );
if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {
printf( "Connection Closed.\n");
break;
}
if (bytesRecv < 0)
return;
printf( "Bytes Recv: %ld\n", bytesRecv );
}
return;
}
下面是服务器端代码:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void main() {
// 初始化
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// 建立socket
SOCKET server;
server = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( server == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// 绑定socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
service.sin_port = htons( 27015 );
if ( bind( server, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf( "bind() failed.\n" );
closesocket(server);
return;
}
// 监听 socket
if ( listen( server, 1 ) == SOCKET_ERROR )
printf( "Error listening on socket.\n");
// 接受连接
SOCKET AcceptSocket;
printf( "Waiting for a client to connect...\n" );
while (1) {
AcceptSocket = SOCKET_ERROR;
while ( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( server, NULL, NULL );
}
printf( "Client Connected.\n");
server = AcceptSocket;
break;
}
// 发送接受数据
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[32] = "Server: Sending Data.";
char recvbuf[32] = "";
bytesRecv = recv( server, recvbuf, 32, 0 );
printf( "Bytes Recv: %ld\n", bytesRecv );
bytesSent = send( server, sendbuf, strlen(sendbuf), 0 );
printf( "Bytes Sent: %ld\n", bytesSent );
return;
}
本程序仅仅描述了同步的情况!
PS:本文转自网络贴吧新红盟吧
============================================================accept()补充
绑定socket后用listen函数去监听,如果有连接请求就把该请求放到等待队列里,等待accept函数来接收。
一旦accept接收成功就创建一个新的socket来处理与client的通讯。
accept()函数
准备好了,系统调用accept()会有点古怪的地方的!
你可以想象发生这样的事情:有人从很远的地方通过一个你在侦听(listen())的端口连接(connect())到你的机器。
它的连接将加入到等待接受(accept())的队列中。你调用accept()告诉它你有空闲的连接。它将返回一个新的套接字文件描述符!
这样你就有两个套接字了,原来的一个还在侦听你的那个端口,新的在准备发送(send())和接收(recv())数据。这就是这个过程!
函数是这样定义的:
#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
sockfd相当简单,是和isten()中一样的套接字描述符。addr是个指向局部的数据结构sockaddr_in的指针。
这是要求接入的信息所要去的地方(你可以测定哪个地址在哪个端口呼叫你)。
在它的地址传递给accept之前,addrlen是个局部的整形变量,设置为 sizeof(struct sockaddr_in)
accept将不会将多余的字节给addr。如果你放入的少些,那么它会通过改变 addrlen 的值反映出来。
同样,在错误时返回-1,并设置全局错误变量 errno。
现在是你应该熟悉的代码片段。
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MYPORT 3490 /*用户接入端口*/
#define BACKLOG 10 /* 多少等待连接控制*/
main()
{
int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */
struct sockaddr_in my_addr; /* 地址信息 */
struct sockaddr_in their_addr; /* connector's address information*/
int sin_size;
/* don't forget your error checking for these calls: */
sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 错误检查*/
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
bzero(&(my_addr.sin_zero); /* zero the rest of the struct */
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
listen(sockfd, BACKLOG);
sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, &their_addr, &sin_size);
...
...
}
注意,在系统调用 send() 和 recv() 中你应该使用新的套接字描述符 new_fd。
如果你只想让一个连接进来,那么你可以使用 close() 去关闭原来的文件描述符sockfd来避免同一个端口更多的连接。
‘伍’ vc网络编程看那本书比较好
《Windows网络编程》这个是基础。有电子版下的
再看《Visual C++网络通信编程实用案例精选》
这些实例书。
一定要先基础,搞清脉络,再看实例。不然你看不懂的,只会照着他打代码。
‘陆’ 帮忙推荐一本vc++环境下经典的网络编程书籍
《Windows 网络编程技术》
‘柒’ Visual C++网络编程经典案例详解的目录
第1篇 Visual C++网络编程基础
第1章 Visual C++网络编程概述(教学视频:21分钟)
1.1 网络基础知识
1.1.1 OSI七层网络模型
1.I.2 TCP/IP协议
1.1.3 C/S编程模型
1.2 网络编程基础
1.2.1 Sockets套接字
1.2.2 网络字节顺序
1.3 WindowsSockets介绍
1.3.1 CAsyncSocket类
1.3.2 CSocket类
1.4 小结
第2章 Socket套接字编程(教学视频:73分钟)
2.1 寻址方式和字节顺序
2.1.1 寻址方式
2.1.2 字节顺序
2.1.3 Socket相关函数
2.2 Winsock网络程序开发流程
2.2.1 VC中创建工程的步骤
2.2.2 Winsock编程流程
2.2.3 基于UDP的Sockets编程
2.2.4.基于UDP的Sockets编程
2.3 网络程序实例应用
2.3.1 TCP客户端程序
2.3.2 TCP服务器程序
2.4 小结
第3章 多线程与异步套接字编程(教学视频:116分钟)
3.1 多线程技术
3.1.1 基本概念
3.1.2 创建线程
3.2 实现线程同步
3.2.1 临界区对象
3.2.2 事件对象
3.2.3 互斥对象
3.3 进程间通信
3.3.1 邮槽
3.3.2 命名管道
3.3.3 匿名管道
3.3.4 小结
3.4 设置I/O模式
3.4.1 异步I/O模式
3.4.2 WSAAsyncSelect方法
3.5 小结
第2篇 Visual C++网络编程典型应用
第4章 FTP浏览器(教学视频:95分钟)
4.1 FTP工作原理
4.1.1 FTP数据结构
4.1.2 FTP数据传输模式
4.1.3 服务器进行连接
4.1.4 登录验证
4.1.5 关闭数据连接
4.1.6 FTP常用命令
4.1.7 数据校验与重发控制
4.2 登录FTP服务器
4.2.1 连接FTP服务器
4.2.2 登录FTP服务器
4.3 FTP文件处理
4.3.1 CSocketFile类的使用
4.3.2 使用CArchive类进行串行化
4.3.3 获取FTP服务器文件信息
4.3.4 上传文件
4.3.5 下载文件
4.4 创建客户端
4.4.1 建立工程
4.4.2 定义CFtp类
4.4.3 使用CFtp类编程
4.5 小结
第5章 网页浏览器(教学视频:72分钟)
5.1 HTTP请求
5.1.1 GET方式
5.1.2 POSI方式
5.1.3 请求消息
5.2 HTTP响应
5.2.1 响应状态信息
5.2.2 响应标题字段信息
5.2.3 实体标题字段信息
5.2.4 实体数据
5.3 制作个性化界面
5.3.1 工具栏编程
5.3.2 添加消息响应
5.3.3 如何实现收藏夹的功能
5.5.4.使用MicrosoftWeb浏览器控件
5.4.1 建立MFC工程
5.4.2 添加控件
5.4.3 控件对象属性方法
5.5 CHtmlView类
5.5.1 CHtmlView类
5.5.2 建立继承关系
5.5.3 地址栏消息响应
5.5.4 实现查看源文件功能
5.5.5 实现刷新功能
5.6 小结
第6章 网络通信器(教学视频:58分钟)
6.1 通信原理
6.1.1 通信连接
6.1.2 发送接收
6.2 发送端程序
6.2.1 创建连接套接字
6.2.2 创建发送套接字
6.2.3 实现发送功能
6.3 接收端程序
6.3.1 监听端口
6.3.2 接收数据
6.4 界面美化编程
6.4.1 界面初始化
6.4.2 设置服务器窗口图标
6.4.3 显示服务器启动时间
6.4.4 服务器状态栏编程
6.5 ,J、结
第7章 邮件收发器(教学视频:107分钟)
7.1 调用Windows自带的邮件发送程序
7.1.1 调用Windows进程
7.1.2 CreateProcess(1函数
7.2 SMTP会话过程
7.2.1 怎么连接服务器
7.2.2 SMTP命令
7.2.3 发送命令与接收响应
7.3 发送邮件
7.3.1 界面设计
7.3.2 界面初始化代码
7.3.3 添加服务器设置对话框
7.3.4 使用服务器设置对话框
7.3.5 记录程序配置信息
7.3.6 设置并连接服务器
7.3.7 构造邮件
7.3.8 发送邮件
7.3.9 发送邮件实例
7.4 接收邮件
7.4.1 POP3简介
7.4.2 接收邮件实例界面
7.4.3 使用接收邮件对话框
7.4.4 接收邮件
7.4.5 实现接收邮件功能
7.4.6 封装客户端发送与接收功能
7.4.7 显示邮件数据
7.4.8 代码分析
7.5 小结
第8章 网络文件传输器(教学视频:87分钟)
8.1 CFile类
8.1.1 构造函数
8.1.2 读写文件
8.1.3 文件关闭
8.1.4 文件定位
……
第9 实用播放器(教学视频:120分钟)
第10 P2P网络播放器(教学视频:107分钟)
第11 Q版聊天软件(学视频:60分钟)
第3篇 Visual C++串口通信
第12 串口通信基础(教学视频:22分钟)
第13 串口通信编程应用(教学视频:69分钟)
第14 VC发送手机短信(教学视频:73分钟)
‘捌’ 想学VC网络编程 但感觉找不到好的资料,,谁能推荐一下不!!!!
<<windows网络与通信设计>> 、<<VC++网络编程经典案例详解>> 目前我也在学vc网络编程,有空可以交流下 QQ314441306
‘玖’ 学visual c++网络编程技术哪本教材不错应从何入手
那要看你现在是什么水品了!你要是vc++还什么都不会呢!建议你还是老老实实从c++基础教程看起,然后vc++,学习网络编程技术有《vc++网络编程经典案例解析》,对于vc++学会的人来说学这个比较好些!网上还有不少关于网络编程类的书籍,自己去找吧。再次就不一一列举!呵呵!
‘拾’ VC 求最最最简单的网络编程代码 ==扔分
把服务器和客户端他们放在两个工程里,先运行服务器,再运行客户端,我想其他网的也没什么问题,应该是你不会配置。我这个不用配置,有问题的话,给我发邮件:[email protected]晚上10点后我会看
服务器端:
#pragma comment(lib,"ws2_32.lib")
#include <iostream>
#include <WINSOCK2.H>
using namespace std;
void WSASTARTUP()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
}
int main(int argc, char * argv[])
{
WSASTARTUP();
SOCKET sockSer = socket(AF_INET, SOCK_STREAM, 0);
//socket地址
SOCKADDR_IN addrSer;
addrSer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6000);
//socket和地址端口绑定
bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
//监听
listen(sockSer, 5);
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn = accept(sockSer, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf(sendBuf, "Welcome to Thor Server!", inet_ntoa(addrClient.sin_addr));
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\n", recvBuf);
closesocket(sockConn);
}
system("PAUSE");
return 0;
}
客户端:
#pragma comment(lib,"ws2_32.lib")
#include <iostream>
#include <WINSOCK2.H>
#include <string>
#include <stdio.h>
using namespace std;
void WSASTARTUP()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
}
int main(int argc, char * argv[])
{
WSASTARTUP();
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSer;
//string ip;
//cout<<"输入服务器IP地址,格式为XX.XX.XX.XX!"<<endl;
//cin>>ip;
addrSer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6000);
connect(sockClient, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s", recvBuf);
//string message;
//cin>>message;
send(sockClient, "你好!~", strlen("你好!~")+1, 0);
closesocket(sockClient);
WSACleanup();
system("PAUSE");
return 0;
}