C++ socket網(wǎng)絡(luò)編程

Socket介紹:

socket即套接字,端口號(hào)拼接到IP地址就構(gòu)成了套接字基公。如果IP地址是169.254.24幅慌,而端口號(hào)是3000欠痴,那么得到套接字就是(169.254.24:3000),即(主機(jī)IP地址:端口號(hào))。
三種不同類型的套接字:
1特占、 (SOCK-STREAM)流式套接字:提供一種可靠的懊纳、面向連接的雙向數(shù)據(jù)傳輸服務(wù)闺兢,實(shí)現(xiàn)了數(shù)據(jù)無(wú)差錯(cuò)、無(wú)重復(fù)的發(fā)送。發(fā)送大批量的數(shù)據(jù)或者對(duì)數(shù)據(jù)傳輸有較高的要求時(shí),可以使用流式套接字泄鹏。
2车猬、 (SOCK-DGRAM)數(shù)據(jù)報(bào)套接字: 提供一種無(wú)連接伏嗜、不可靠的雙向數(shù)據(jù)傳輸服務(wù)。數(shù)據(jù)包以獨(dú)立的形式被發(fā)送轩猩,數(shù)據(jù)在傳輸過(guò)程中可能會(huì)丟失或重復(fù),并且不能保證在接收端按發(fā)送順序接收數(shù)據(jù)热鞍。出現(xiàn)差錯(cuò)的可能性較小或允許部分傳輸出錯(cuò)的應(yīng)用場(chǎng)合澄港,可以使用數(shù)據(jù)報(bào)套接字狱意。
3藏姐、(SOCK-RAW)原始套接字:該套接字允許對(duì)較低層協(xié)議(如IP或ICMP)進(jìn)行直接訪問(wèn),常用于網(wǎng)絡(luò)協(xié)議分析护姆,檢驗(yàn)新的網(wǎng)絡(luò)協(xié)議實(shí)現(xiàn),也可用于測(cè)試新配置或安裝的網(wǎng)絡(luò)設(shè)備添祸。

客戶端/服務(wù)端模式:

網(wǎng)絡(luò)架構(gòu)使用客戶端(Client)-服務(wù)器(Server)模式(簡(jiǎn)稱C/S)亚侠,即客戶端向服務(wù)器發(fā)出請(qǐng)求滞谢,服務(wù)器接收請(qǐng)求后禾酱,提供相應(yīng)的服務(wù)垦江。
服務(wù)端:建立socket,聲明自身的端口號(hào)和地址并綁定到socket,使用listen打開(kāi)監(jiān)聽(tīng)瓢剿,然后不斷用accept去查看是否有連接,如果有悠轩,捕獲socket火架,并通過(guò)recv獲取消息的內(nèi)容音比,通信完成后調(diào)用closeSocket關(guān)閉這個(gè)對(duì)應(yīng)accept到的socket骚亿,如果不再需要等待任何客戶端連接泥技,那么用closeSocket關(guān)閉掉自身的socket。
客戶端:建立socket兼贸,通過(guò)端口號(hào)和地址確定目標(biāo)服務(wù)器段直,使用Connect連接到服務(wù)器,send發(fā)送消息溶诞,等待處理鸯檬,通信完成后調(diào)用closeSocket關(guān)閉socket。

TCP編程步驟:

一螺垢、服務(wù)端

1喧务、加載套接字庫(kù),創(chuàng)建套接字(WSAStartup()/socket());
2枉圃、綁定套接字到一個(gè)IP地址和一個(gè)端口上(bind());
3功茴、將套接字設(shè)置為監(jiān)聽(tīng)模式等待連接請(qǐng)求(listen());
4孽亲、請(qǐng)求到來(lái)后坎穿,接受連接請(qǐng)求,返回一個(gè)新的對(duì)應(yīng)于此次連接的套接字(accept())返劲;
5玲昧、用返回的套接字和客戶端進(jìn)行通信(send()/recv());
6篮绿、返回孵延,等待另一個(gè)連接請(qǐng)求;
7亲配、關(guān)閉套接字尘应,關(guān)閉加載的套接字庫(kù)(closesocket()/WSACleanup())惶凝;

二、客戶端

1犬钢、加載套接字庫(kù)梨睁,創(chuàng)建套接字(WSAStartup()/socket());
2娜饵、向服務(wù)器發(fā)出連接請(qǐng)求(connect())坡贺;
3、和服務(wù)器進(jìn)行通信(send()/recv())箱舞;
4遍坟、關(guān)閉套接字,關(guān)閉加載的套接字庫(kù)(closesocket()/WSACleanup())晴股;

TCP服務(wù)端代碼

#include "pch.h"
#include <iostream> 
#include <winsock2.h>  
 
#pragma comment(lib,"ws2_32.lib")  
using namespace std;
 
int main(int argc, char* argv[])
{
    //初始化WSA  
    WORD sockVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(sockVersion, &wsaData) != 0)
    {
        return 0;
    }
 
    //創(chuàng)建套接字  
    SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (slisten == INVALID_SOCKET)
    {
        cout << "create socket error !" << endl;
        return 0;
    }
 
    //綁定IP和端口  
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(8888);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        cout << "bind error !" << endl;
    }
 
    //開(kāi)始監(jiān)聽(tīng)  
    if (listen(slisten, 5) == SOCKET_ERROR)
    {
        cout << "listen error !" << endl;
        return 0;
    }
 
    //循環(huán)接收數(shù)據(jù)  
    SOCKET sClient;
    sockaddr_in remoteAddr;
    int nAddrlen = sizeof(remoteAddr);
    char revData[255];
    while (true)
    {
        cout << "阻塞愿伴。。。。等待連接刷后。碟联。湾宙。" << endl;
        sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
        if (sClient == INVALID_SOCKET)
        {
            cout << "accept error !" << endl;
            continue;
        }
 
        cout << "接受到一個(gè)連接:" << inet_ntoa(remoteAddr.sin_addr) << endl;
 
        //接收數(shù)據(jù)  
        int ret = recv(sClient, revData, 255, 0);
        if (ret > 0)
        {
            revData[ret] = 0x00;
            printf(revData);
        }
 
        //發(fā)送數(shù)據(jù)  
        const char * sendData = "你好,TCP客戶端!\n";
        send(sClient, sendData, strlen(sendData), 0);
        closesocket(sClient);
    }
 
    closesocket(slisten);
    WSACleanup();
    return 0;
}

TCP客戶端代碼

#include "stdafx.h"
#include<winsock2.h>
#include<iostream>
#include<string>
 
using namespace std;
#pragma comment(lib, "ws2_32.lib")
 
int main()
{
    WORD sockVersion = MAKEWORD(2, 2);
    WSADATA data;
    if (WSAStartup(sockVersion, &data) != 0)
    {
        return 0;
    }
 
    while (true) 
    {
        SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sclient == INVALID_SOCKET)
        {
            cout << "invalid socket!" << endl;
            return 0;
        }
 
        sockaddr_in serAddr;
        serAddr.sin_family = AF_INET;
        serAddr.sin_port = htons(8888);
        serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
        {  
            //連接失敗 
            cout << "connect error !" << endl;
            closesocket(sclient);
            return 0;
        }
 
        string data;
        cin >> data;
        const char * sendData;
        sendData = data.c_str();   //string轉(zhuǎn)const char* 
                                   
        /*
        send()用來(lái)將數(shù)據(jù)由指定的socket傳給對(duì)方主機(jī)
        int send(int s, const void * msg, int len, unsigned int flags)
            s為已建立好連接的socket,msg指向數(shù)據(jù)內(nèi)容幻妓,len則為數(shù)據(jù)長(zhǎng)度,參數(shù)flags一般設(shè)0
            成功則返回實(shí)際傳送出去的字符數(shù)劫拢,失敗返回-1肉津,錯(cuò)誤原因存于error
        */
        send(sclient, sendData, strlen(sendData), 0);
        
        char recData[255];
        int ret = recv(sclient, recData, 255, 0);
        if (ret>0)
        {
            recData[ret] = 0x00;
            cout << recData << endl;
        }
        closesocket(sclient);
    }
 
    WSACleanup();
 
    system("pause");
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舱沧,隨后出現(xiàn)的幾起案子妹沙,更是在濱河造成了極大的恐慌,老刑警劉巖熟吏,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件距糖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡分俯,警方通過(guò)查閱死者的電腦和手機(jī)肾筐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門哆料,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缸剪,“玉大人,你說(shuō)我怎么就攤上這事东亦⌒咏冢” “怎么了唬渗?”我有些...
    開(kāi)封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奋渔。 經(jīng)常有香客問(wèn)我镊逝,道長(zhǎng),這世上最難降的妖魔是什么嫉鲸? 我笑而不...
    開(kāi)封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任撑蒜,我火速辦了婚禮,結(jié)果婚禮上玄渗,老公的妹妹穿的比我還像新娘座菠。我一直安慰自己,他們只是感情好藤树,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布浴滴。 她就那樣靜靜地躺著,像睡著了一般岁钓。 火紅的嫁衣襯著肌膚如雪升略。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天屡限,我揣著相機(jī)與錄音品嚣,去河邊找鬼。 笑死钧大,一個(gè)胖子當(dāng)著我的面吹牛腰根,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拓型,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼额嘿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了劣挫?” 一聲冷哼從身側(cè)響起册养,我...
    開(kāi)封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎压固,沒(méi)想到半個(gè)月后球拦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帐我,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年坎炼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拦键。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谣光,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芬为,到底是詐尸還是另有隱情萄金,我是刑警寧澤蟀悦,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站氧敢,受9級(jí)特大地震影響日戈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孙乖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一浙炼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唯袄,春花似錦鼓拧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至梅掠,卻和暖如春酌住,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阎抒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工酪我, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人且叁。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓都哭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親逞带。 傳聞我的和親對(duì)象是個(gè)殘疾皇子欺矫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容