C++ 網(wǎng)絡(luò)編程 總結(jié)
第一次用C++寫程序,對C++ 只是菜鳥級別的,倒是對C#很熟悉。兩者有很大的相似性。但也有不同。
首先寫了一個網(wǎng)絡(luò)通訊用的小的MFC程序。發(fā)現(xiàn)
(1)MFC寫界面真的好麻煩呀。用C#寫的tab 分分鐘搞定的事,用C++害得我寫了兩天.關(guān)鍵是不熟練. 還有l(wèi)ist control 控件的圖標(biāo)顯示. 真是很麻煩
不過,由于最后的 detch() 函數(shù)執(zhí)行后,就真正顯示出來了.這些具體的小細(xì)節(jié),一般在 書上都沒有寫.
(2)用C++ 寫類的特征,基本上與C#是相似的.
說一下網(wǎng)絡(luò)編程的問題吧
1\一開始并不清楚 C++ 寫程序用的網(wǎng)絡(luò)套接字,三類的不一樣的地方.總以為我用的VS2013,用最高級別的套接字應(yīng)該更容易一些,于是選用了CSOCKET 結(jié)果由于這個套接字是阻塞模式,結(jié)果被卡住了,卡住不知道如何做了.如果對方設(shè)備沒有反應(yīng),最不能死等吧,這樣不行.
于上網(wǎng)上搜索,發(fā)現(xiàn)一篇文章寫到 給 CSocket 加上超時.于時照抄照搬著做了一遍,可惜失敗了. 怎么查也查不出原因. 按原文章一字一句的比較,也沒有找出原因來.失敗換思路
2\想到低一點(diǎn)的 CAsyncSocket 是異步操作的.這樣總可以了吧不會阻塞了吧.但是回調(diào)函數(shù)使得處理起來也不方便.在什么時候做處理,就需要消息做處理.但是也很麻煩.
3\于是,找出書來,大部分書上對于網(wǎng)絡(luò)部分只是介紹了一個最基本的 Socket ,看起來也挺簡單的. 就先試一下這個最基本的吧.
沒想到 30分鐘后,網(wǎng)絡(luò)程序測試成功. 而且有超時接收,超時發(fā)送,等.正合我意.
原來最基本的,才是最好的.
總結(jié)一下:
SOCKET的操作方法
以下是一個網(wǎng)絡(luò)客戶端的例子:
// client.cpp
#include <iostream>
#include <cstdio>
#include <Winsock2.h>
using namespace std;
int main()
{
// 加載socket動態(tài)鏈接庫(dll)
WORD wVersionRequested;
WSADATA wsaData; // 這結(jié)構(gòu)是用于接收Wjndows Socket的結(jié)構(gòu)信息的
int err;
wVersionRequested = MAKEWORD( 1, 1 ); // 請求1.1版本的WinSock庫
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return -1; // 返回值為零的時候是表示成功申請WSAStartup
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {
// 檢查這個低字節(jié)是不是1,高字節(jié)是不是1以確定是否我們所請求的1.1版本
// 否則的話,調(diào)用WSACleanup()清除信息,結(jié)束函數(shù)
WSACleanup( );
return -1;
}
// 創(chuàng)建socket操作,建立流式套接字,返回套接字號sockClient
// SOCKET socket(int af, int type, int protocol);
// 第一個參數(shù),指定地址簇(TCP/IP只能是AF_INET,也可寫成PF_INET)
// 第二個,選擇套接字的類型(流式套接字),第三個,特定地址家族相關(guān)協(xié)議(0為自動)
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
// 將套接字sockClient與遠(yuǎn)程主機(jī)相連
// int connect( SOCKET s, const struct sockaddr* name, int namelen);
// 第一個參數(shù):需要進(jìn)行連接操作的套接字
// 第二個參數(shù):設(shè)定所需要連接的地址信息
// 第三個參數(shù):地址的長度
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 本地回路地址是127.0.0.1;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s\n", recvBuf);
send(sockClient, "Attention: A Client has enter...\n", strlen("Attention: A Client has enter...\n")+1, 0);
printf("我們可以聊五句話");
int n = 5;
do{
printf("\n還剩%d次:", n);
char talk[100];
printf("\nPlease enter what you want to say next(\"quit\"to exit):");
gets(talk);
send(sockClient, talk, strlen(talk)+1, 0); // 發(fā)送信息
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s Says: %s\n", "Server", recvBuf); // 接收信息
}while(--n);
printf("End linking...\n");
closesocket(sockClient);
WSACleanup(); // 終止對套接字庫的使用
printf("\n");
system("pause");
return 0;
}
關(guān)于超時的處理方法
在send(),recv()過程中有時由于網(wǎng)絡(luò)狀況等原因,收發(fā)不能預(yù)期進(jìn)行,而設(shè)置收發(fā)超時控制:
在Linux下需要注意的是時間的控制結(jié)構(gòu)是struct timeval而并不是某一整型數(shù),
在windows下是這樣寫的:
int nNetTimeout=1000;//1秒,
//設(shè)置發(fā)送超時
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//設(shè)置接收超時
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
這樣做在Linux環(huán)境下是不會產(chǎn)生效果的,須如下定義:
struct timeval timeout = {3,0};
//設(shè)置發(fā)送超時
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//設(shè)置接收超時
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));
有兩點(diǎn)注意就是:
1)recv ()的第四個參數(shù)需為MSG_WAITALL(設(shè)置MSG_DONTWAIT可以不用阻塞在建立連接后在等等接收數(shù)據(jù)),在阻塞模式下不等到指定數(shù)目的數(shù)據(jù)不會返回,除非超時時間到。還要注意的是只要設(shè)置了接收超時,在沒有MSG_WAITALL時也是有效的。說到底超時就是不讓你的程序老在那兒等,到一定時間進(jìn)行一次返回而已。
2)即使等待超時時間值未到,但對方已經(jīng)關(guān)閉了socket, 則此時recv()會立即返回,并收到多少數(shù)據(jù)返回多少數(shù)據(jù)。
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲方式詳解
- 01-10C語言字符串操作總結(jié)大全(超詳細(xì))


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文


