线程与网络编程(第四节:缓冲区与按字节传递)
2016-06-12 16:00
302 查看
1.发送接收缓冲区
一块内存:缓冲区
工作过程:发送方经过sendTo()发送到缓冲区,然后由操作系统自动取走,经网络传输存放到对方的缓冲区,然后经RecvFrom()取得内容。
由于存放数据与发送数据存在时间差,如果存的太多,可能会导致丢失;同理,接收时也类似。
可能的解决方案:设置大一点的缓冲区
具体代码:
发送方:
接收方:
扩大缓冲区这种并不一定能解决
使用Udp考虑的问题是:(1)发送是否均匀(2)接收是否及时(3)数据带宽是否超过实际带宽。
丢包不可避免,UDP适用于允许丢包的场景。
2.按字节传输
网络上的数据是按字节一个一个传递的。
网络字节传递:按大端方式传递
传送:
接收:
大端小端,需要根据具体传输时的需要来解决。网络传输时根据具体实际传。
一块内存:缓冲区
工作过程:发送方经过sendTo()发送到缓冲区,然后由操作系统自动取走,经网络传输存放到对方的缓冲区,然后经RecvFrom()取得内容。
由于存放数据与发送数据存在时间差,如果存的太多,可能会导致丢失;同理,接收时也类似。
可能的解决方案:设置大一点的缓冲区
具体代码:
发送方:
#include<stdio.h> #include "osapi/osapi.h" int main(){ //打开端口号 printf("发送方......\n"); OS_SockAddr local("127.0.0.1",9000); OS_UdpSocket sock; sock.Open(local,true); /* 加了一段内容,设置大一点的缓冲区,但不一定有效。 */ //open之后设置 if(1) { // 设置SendBuf的大小 int bufsize = 128*1024; // 128K int ret = setsockopt(sock.hSock,SOL_SOCKET, SO_SNDBUF, (const char*)&bufsize,sizeof(int)); if(ret < 0) { // 设置失败 printf("设置失败!\n"); } } while (1) { //让用户输入一段文本 char buf[128]; OS_SockAddr peer("127.0.0.1",9001); printf(">>"); gets(buf);//输入文字内容 int n=strlen(buf); sock.SendTo(buf,n,peer); //退出 if (strcmp(buf,"bye")==0) { break; } } sock.Close();//关闭端口号 return 0; }
接收方:
#include <stdio.h> #include "osapi/osapi.h" int main(){ printf("接收方....\n"); OS_SockAddr local("127.0.0.1",9001); OS_UdpSocket sock; sock.Open(local,true);//打开端口号 //设置接收方缓冲区 if(1) { // 设置RecvBuf的大小 int bufsize = 128*1024; // 128K int ret = setsockopt(sock.hSock,SOL_SOCKET, SO_RCVBUF,(const char*)&bufsize,sizeof(int)); if(ret < 0) { printf("设置失败......\n"); } } while (1) { char buf[128]; OS_SockAddr peer;//对端 //接收 int n=sock.RecvFrom(buf,128,peer); if (n<0) { break; } buf =0; printf("接收内容:%s\n",buf); } sock.Close(); }
扩大缓冲区这种并不一定能解决
使用Udp考虑的问题是:(1)发送是否均匀(2)接收是否及时(3)数据带宽是否超过实际带宽。
丢包不可避免,UDP适用于允许丢包的场景。
2.按字节传输
网络上的数据是按字节一个一个传递的。
网络字节传递:按大端方式传递
传送:
unsigned int a=0x12345678; unsigned char bytes[4]; itob_32(a,bytes);//转成大端 sock.sendTo(bytes,4,peer);
接收:
void print_bytes(void* buf, int n) { unsigned char* bytes = (unsigned char*) buf; for(int i=0; i<n; i++) { printf("%02X ", bytes[i]); if( (i+1)%16 == 0) printf("\n"); } } 主函数中接收: printf("接收方....\n"); OS_SockAddr local("127.0.0.1",9001); OS_UdpSocket sock; sock.Open(local,true);//打开端口号 while (1) { unsigned char buf[128]; OS_SockAddr peer; // 对方的地址 int n = sock.RecvFrom(buf, 128, peer);//接收字节数 if(n <= 0) { break; } // 结束 // 按字节打印接收到的数据 printf("Got:"); print_bytes(buf,n); unsigned int a = btoi_32be(buf); printf("Got a number: %08X \n", a);
大端小端,需要根据具体传输时的需要来解决。网络传输时根据具体实际传。
相关文章推荐
- 应用领航:盘点那些年我们一起追过的OS
- 无奇不有!盘点各国自己开发的操作系统
- C#线程间不能调用剪切板的解决方法
- Lua下基本的网络编程示例
- 可自定义oem的萝卜家园 Ghost XP 新春装机版 V200801 下载
- SQL Server 数据页缓冲区的内存瓶颈分析
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- 简单对比C#程序中的单线程与多线程设计
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C#实现判断操作系统是否为Win8以上版本
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- linux网络编程用到的网络函数详解用和使用示例
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法