网络与线程编程(第七节:TCP与数据包)

1.TCp(2)发送接收缓冲区
Tcp的发送模式基本等同UDP,但不同点在于UDP是包式存取,而TCP是流式存取,每个包不带地址。
发送:send(“Hello”)与send(“World’);可能同时被一起取走;而发送send(“HelloWorld”);//有可能只取走hello。
问题:对于TCp socket,如何判断Recv()已取回全部数据?(何时超时)
定义边界:a->b(请求);b->a(响应),a->b(请求),b->a(xiangying);
在设计交互协议时,需要自己定义消息的边界。
方法1:先定义长度,后发数据;
方法2:每段加结束符。
流式存取:有多少取多少(不管先后顺序)。
例1:流式存取
Client:

// 连接服务器
    OS_SockAddr serv_addr("127.0.0.1", 9555);
    if( client_sock.Connect( serv_addr ) < 0)
    {
        printf("无法连接服务器!\n");
        return -1;
    }

    char buf[1024];
    int n;
    client_sock.Send("hello", 5);
    client_sock.Send("world", 5);

Server:

int TcpConn::Routine()
{
    // 为client提供服务
     char buf[1024];
    int n ;

    //OS_Thread::Msleep(5000);

    // 接收客户的请求
    n = m_WorkSock.Recv(buf, 1023);
    buf[n] = 0;
    printf("客户请求: %s \n", buf);

    // 应答客户
    strcpy(buf,"yes,ok!");
    n=strlen(buf);
    m_WorkSock.Send(buf, n);

    // 关闭socket
    m_WorkSock.Close();

    return 0;
}

接收结果:helloworld,有多少,去多少!

例2:定义边界(先发送长度,再发数据)
client:

unsigned char bytes[2];
        itob_16be(10, bytes);//按大端
        client_sock.Send(bytes, 2);//发送数据大小
        client_sock.Send("helloworld", 10);//发送数据

Server:

// 为client提供服务
    unsigned char buf[1024];
    int n ;
    //m_WorkSock.Recv(buf,2);//接收两个字节的数据,但可能娶不到
    // 使用边界
    TcpHelper::WaitBytes(m_WorkSock,buf,2);
    unsigned short count=btoi_16be(buf);//接收多长数据
    n=TcpHelper::WaitBytes(m_WorkSock,buf,count);
    buf[n]=0;
    printf("客户请求: %s \n", buf);
    m_WorkSock.Send("yes,OK!",8);
    // 关闭socket
    m_WorkSock.Close();

    return 0;

阻塞:send满阻塞,recv空阻塞(这是默认方式)
例3:设置缓冲区大小

//扩大缓存
    if(1)
    {
        // 获取Sendbuf的大小 
        int bufsize = 0; // 8k
        socklen_t len = 4;
        int ret = getsockopt(client_sock.hSock,SOL_SOCKET,
            SO_SNDBUF,
            (char*)&bufsize,&len);
        if(ret < 0)
        {
            // 设置失败
            printf("failed to get option!\n");
        }
    }

    if(1)
    {
        // 设置SendBuf的大小
        int bufsize = 128*1024; // 128K
        int ret = setsockopt(client_sock.hSock,SOL_SOCKET,
            SO_SNDBUF,
            (const char*)&bufsize,sizeof(int));
        if(ret < 0)
        {
            // 设置失败
        }
    }

TCP设置缓冲区是有用的。

2.数据包的传输
发送:OS把数据通过网卡,上传至交换机;
接收:OS通过网卡获得数据包。
UDP丢包:无法通知丢包;
TCP传输:传输后,OS会发一个ACK包,否则重传;
TCP传输是可靠传输,会失败;UDP是不会失败(只发送,不管理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值