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;
}