码迷,mamicode.com
首页 > 其他好文 > 详细

TCP/UDP通信解疑

时间:2018-03-21 23:20:16      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:一个   因此   code   使用   content   lap   splay   需要   can   

一、TCP是面向流的通信,这个什么意思呢,你read一下,可能从流的任何一点拿数据;然后呢,你需要对应用层的数据做封包处理。

封包最主要的一点是数据类型和数据长度,说到这里,为何http请求没有指明数据长度呢,以前http通信是短连接只有一问一答,因此不需要数据长度;

后来http1.1出现keep-alive的长连接,但是它有诸如content-length等的报文头,而且http具有明确的开始点。

二、UDP是面向数据报的通信,它的使用简单,但有其最大报文不能超过64k,否则send失败;包之间具有明确界限,每次recv都会读取一个包,假设应用给

的buffer不够它本身的长度,其余部分也被抛弃。

以下是linux gcc 4.84的验证:

技术分享图片
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

void client_p()
{
    sleep(1);//can use semphore
    struct sockaddr_in addr;
    int sock;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("client socket error");
        return NULL;
    }
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8765);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    char buff[10];
    int n = 0;
    int len = sizeof(addr);
    do
    {
        n = sendto(sock, "123456789", 10, 0, (struct sockaddr*)&addr, sizeof(sockaddr));
        if (n < 0)
        {
            perror("sendto server 1 error");
            break;
        }
        n = recvfrom(sock, buff, 10, 0, (struct sockaddr*)&addr, &len);
        //if
        n = sendto(sock, "987654321", 10, 0, (struct sockaddr*)&addr, sizeof(sockaddr));
        //if
    } while (0);
    close(sock);
    return NULL;
}
void server_p()
{
    struct sockaddr_in addr;
    int sock;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("server socket error");
        return NULL;
    }
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8765);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    char buff[10];
    int n = 0;
    int len = sizeof(addr);
    do
    {
        if (bind(sock, (struct sockaddr*)&addr, len) < 0)
        {
            perror("bind error");
            break;
        }
        n = recvfrom(sock, buff, 4, 0, (struct sockaddr*)&addr, &len);
        if (n < 0)
        {
            perror("recvfrom client 1 error");
            break;
        }
        else 
        {
            printf("recv 1:%s\n", buff);//buff is a string
        }
        n = sendto(sock, "1", 1, 0, (struct sockaddr*)&addr, sizeof(sockaddr));
        //if (n < 0)
        n = recvfrom(sock, buff, 4, 0, (struct sockaddr*)&addr, &len);
        if (n < 0)
        {
            perror("recvfrom client 2 error");
            break;
        }
        else
        {
            printf("recv 2:%s\n", buff);//buff is a string
        }
    } while (0);
    close(sock);
    return NULL;
}
int main(int argc, char**argv)
{
    int ret = 0;
    pthread_t client, server;
    ret = pthread_create(&server, NULL, (void*)server_p, NULL);
    //if
    ret = pthread_create(&client, NULL, (void*)client_p, NULL);
    //if
    pthread_join(server);
    pthread_join(client);
    return 0;
}
View Code

 输出结果是:

1234

9876

TCP/UDP通信解疑

标签:一个   因此   code   使用   content   lap   splay   需要   can   

原文地址:https://www.cnblogs.com/green-crosswalk/p/8620275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!