线程与网络编程(第四节:缓冲区与按字节传递)

1.发送接收缓冲区
一块内存:缓冲区
工作过程:发送方经过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[n]=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);

大端小端,需要根据具体传输时的需要来解决。网络传输时根据具体实际传。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值