TCP/UDP通信解疑

Posted green-crosswalk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP/UDP通信解疑相关的知识,希望对你有一定的参考价值。

一、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通信解疑的主要内容,如果未能解决你的问题,请参考以下文章

[osg][osgEarth]基于qt代码实现:TCP|UDP与飞行模拟软件JSBSim的通信,现实模型飞行!

TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)UDP客户端

通信协议 HTTP TCP UDP

27.Socket,TCP,UDP,HTTP基本通信原理

TCP和UDP使用同一端口通信

SOCKET与TCP,UDP有啥关系?