一、UDP服务端
socket bind //绑定 recvfrom
ssize_t recvfrom(int sockfd,    socket的fd
                            void *buf,    保存数据的一块空间的地址 
                           size_t len,    这块空间的大小 
                             int flags,     0  默认的接收方式 --- 阻塞方式 
  struct sockaddr *src_addr,   用来保存发送方的地址信息 
            socklen_t *addrlen );    表示发送方实际的地址信息大小
返回值:成功 返回接收到的字节数 ,失败 -1
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
 功能:如果该函数在服务器端调用,则表示将参数1相关的文件描述符文件与参数2 指定的接口地址关联,用于从该接口接受数据。
如果该函数在客户端调用,则表示要将数据从参数1所在的描述符中取出并从参数2所在的接口设备上发送出去。
sockfd 之前通过socket函数创建的文件描述符,套接字id
my_addr 是物理接口的结构体指针。表示该接口的信息
注意:如果是客户端,则该函数可以省略,由默认接口发送数据。
int main(int argc, const char *argv[])
{
    int fd = socket(AF_INET,SOCK_DGRAM,0);
    if (fd < 0)
    {
        perror("socket fail");
        return -1;
    }
    printf("fd = %d\n",fd);
    
    struct sockaddr_in seraddr;
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(50000);
    seraddr.sin_addr.s_addr = inet_addr("192.168.147.1");
    if(bind(fd, (struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
    {
        perror("bind fail");
        return -1;
    }
    struct sockaddr_in srcaddr;
    socklen_t addrlen = sizeof(srcaddr);
    char buf[1024];
    while(1)
    {
        recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&srcaddr, &addrlen);
        printf("---------------------------\n");
        printf("IP   = %s\n", inet_ntoa(srcaddr.sin_addr));
        printf("post = %d\n", ntohs(srcaddr.sin_port));
        printf("buf = %s\n", buf);
        printf("---------------------------\n");
    }
    return 0;实现一个UDP的回发:

二、TCPc/s模型
1.TCP客户端
建立连接 :  1.socket               2. bind //可选              3.connect       ....
 通信过程 :1.read                    2.write                          3.close 
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:该函数固定有客户端使用,表示从当前主机向目标机发起链接请求。
参数:sockfd 本地socket创建的套接子id
             addr 远程目标主机的地址信息。
              addrlen: 参数2的长度。
返回值:成功 0,失败 -1;
    int fd = socket(AF_INET,SOCK_STREAM,0);
    if(fd < 0)
    {
        perror("socket fail");
        return -1;
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(50000);
    seraddr.sin_addr.s_addr = inet_addr("192.168.159.130");
    if(connect(fd,(const struct sockaddr *)&seraddr
               ,sizeof(seraddr)) < 0)
    {
        perror("connect fail");
    }2.TCP服务器
建立连接: 1.socket 2.bind 3.listen客户端的连接请求
4.accept ---这一步完成之后 连接就建立好了,之后就可以收发数据 .....
通信过程:1.read 2.write 3.close
int listen(int sockfd, int backlog);
函数功能:将套接字文件描述符从主动转为被动文件描述符,然后用于被动监听客户端的连接
函数返回值:成功返回0,失败返回-1, errno被设置
参数:sockfd 表示socket创建的套接字文件描述符
     backlog 指定队列的容量
    int listen_fd = socket(AF_INET,SOCK_STREAM,0);
    if(listen_fd < 0)
    {
        handle_error("socket fail");
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(50000);
    seraddr.sin_addr.s_addr = inet_addr("192.168.159.130");
    if(bind(listen_fd,(const struct sockaddr *)&seraddr
            ,sizeof(seraddr)) < 0)
    {
        handle_error("bind fail");
    }
        if(listen(listen_fd, 5) < 0)
        {
            handle_error("listen fail");
        }
        int connfd = accept(listen_fd, NULL, NULL);
        if(connfd < 0)
        {
            handle_error("accept fail");
        }
        printf("connfd = %d\n", connfd);
 tcp如何建立连接--------tcp三次握手  
断开连接 tcp --------四次回收
实现一个tcp的回发:



![Auto CAD 常用指令汇总 [持续更新]](https://img-blog.csdnimg.cn/img_convert/5d4fc57b29a8c13f92ad25b8f5eb2f58.png)




![Edge-TTS:微软推出的,免费、开源、支持多种中文语音语色的AI工具[工具版]](https://i-blog.csdnimg.cn/direct/bd393adfc52c412585c8084f38f768ef.png)










