C++網路Socket

來源:互聯網
上載者:User

標籤:c_str   host   網路   hello   amp   space   cal   空間   現象   

【多機測試】
若沒有多台電腦,可以使用虛擬機器

有多台電腦,串連交換器

觀察IP
ipconfig(Linux下是ifconfig)

檢測連通性
ping


【發送接收緩衝區】

SendTo()

a)存入資料和發送資料存在時間差
b)如果存入資料太快,太多,則發送緩衝區會滿

RecvFrom()

a)不論是否取,OS總是把資料收下存好
b)RecvFrom是從RecvBuf裡取走現成的資料,如果不及時取,則緩衝區滿。

 

緩衝區滿的處理
發送資料(兩種選擇)
(1)直到緩衝區有剩餘空間-阻塞
(2)新發送的資料沒有存入緩衝區

接受資料(兩種選擇)
(1)新資料不被接受
(2)刪除緩衝區已有資料,存放新的資料

丟包現象

設定發送/接受緩衝區的大小

if(1){int bufsize=128*1024;int ret=setsockopt(sock.hSock,SOL_SOCKET,SO_SNDBUF,//SO_RCVBUF(const char *)&bufsize,sizeof(int));}

  

【丟包】
一般情況下設定緩衝區大小並不能解決丟包問題
(1)發送是否均勻
(2)接受是否及時
(3)資料頻寬是否已經超過實際傳輸寬度

另外,即使HostA和HostB處理都沒問題,網路上任意一個中間節點裝置在轉寄該包時都有可能丟包。

結論:對UDP來說,丟包“家常便飯”,設計時考慮這一點


【網路位元組序】
網路上的資料是一個位元組一個位元組地串列傳輸的
"hello"
h->68
e->65
l->6C
l->6C
o->6F

unsigned int a=0x12345678
它在記憶體的排列
78 56 34 12

規定
規定低位元組在前,則稱為小端
規定高位元組在前,則稱為大端

大端與小端是一套(硬體和軟體),我們見到的主流都是小端
如intel/AMD,很少有大端系統

【網路傳輸時】
unsigned int a=0x12345678
如12 34 56 78(大端)
如78 56 34 12(小端)

慣例都是按大端傳輸
big-endian

一個int型資料佔4個位元組,下面按大端傳輸int型資料
【觀察】

//HostA#include<iostream>using namespace std;#include "afos/AfSocket.h"void Endian_intToChar(int temp,char bytes[]){bytes[0]=(char)(temp >> 24);bytes[1]=(char)(temp >> 16);bytes[2]=(char)(temp >> 8);bytes[3]=(char)(temp);}int main(){//發送方AfSockAddr local("192.168.1.105",9000);//發送方地址AfUdpSocket soc;soc.Open(local,true);cout<<"發送方-連接埠9000 ->"<<endl;while (1){cout<<"please push Enter!"<<endl;getchar();//每按一次斷行符號...AfSockAddr peer("192.168.1.105",9001);char bytes[4];int temp=0x34560012;//int型資料的傳輸不再深究Endian_intToChar(temp,bytes);soc.SendTo(bytes,4,peer);}soc.Close();return 0;}

  

//HostB#include<iostream>using namespace std;#include "afos/AfSocket.h"int Endian_CharToInt(char bytes[],int n)//四個位元組char轉為一個int型資料{int temp=0;temp+=(bytes[0]<<24);temp+=(bytes[1]<<16);temp+=(bytes[2]<<8);temp+=(bytes[3]);return temp;}int main(){//接受方AfSockAddr local("192.168.1.105",9001);//AfSockAddr local("192.168.1.104",9001);//接收方地址AfUdpSocket soc;soc.Open(local,true);cout<<"接收到-連接埠9001->"<<endl;char buffer[128];while (1){AfSockAddr peer;int len=soc.RecvFrom(buffer,128,peer);buffer[len]=‘\0‘;if (len>0){int temp;temp=Endian_CharToInt(buffer,len);printf("%08x\n",temp);}if (strcmp("quit",buffer)==0){break;}}soc.Close();return 0;}

  

【預設分配的連接埠號碼】
【連接埠的佔用】
【多個發送方,一個接收方】
【阻塞與逾時】

【1】預設分配的連接埠號碼
發送方可以不顯示指定連接埠號碼
AfUdpSocket soc;
soc.Open();

可以查看自動分配的連接埠號碼
AfSockAddr local;
sock.GetLocalAddr(local);
unsigned int port=local.GetPort();
printf("local port:%d\n",port);

注意:在發送資料的時候,才會自動分配連接埠。

【2】連接埠的佔用
當連接埠處於佔用時,再建立一個Socket,還使用相同的連接埠,則建立失敗,sock.Open()返回-1

一般設為可重用
sock.Open(local,true);//true允許重用,false不允許重用

 

【3】多個發送方,一個接收方

是誰發來的
string peer_ip=peer.GetIp_str();
int peer_port=peer.GetPort();
printf("from: IP->%s Port->%d",peer_ip.c_str(),peer_port);


【4】阻塞與逾時

sock.RecvFrom()緩衝區無資料則等待,即阻塞,可設定最大時間
設定接收逾時

sock.SetOpt_RecvTimeout(3000);//毫秒設定接收逾時

 

AfUdpSocket soc;
soc.SetOpt_RecvTimeout(3000);//毫秒設定接收逾時


int len=soc.RecvFrom(buffer,128,peer);


if (len<0)
{
printf("got %d\n",len);
}

 

 

非阻塞,定時查看(輪訓),有資料返回0,無資料返回-1

 

C++網路Socket

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.