标签: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_str host 网络 hello amp space cal 空间 现象
原文地址:http://www.cnblogs.com/void-m/p/6395277.html