IT袋

当前位置:主页 > 经验教程 > 建站编程 >

tcp网络通信的基本流程

tcp网络通信的基本流程 TCP网络通信流程概要

时间:2024-01-09 15:59:03 来源:IT袋 作者:马勇
导读:tcp网络通信的基本流程,跟大家聊一聊tcp网络通信的基本流程的相关经验,接下来就是全面介绍。 不管多么复杂的服务器或客户端程序,其网络通信的基本原理一定如下所述: 对于服务器,其通

tcp网络通信的基本流程

跟大家聊一聊tcp网络通信的基本流程的相关经验,接下来就是全面介绍。

不管多么复杂的服务器或客户端程序,其网络通信的基本原理一定如下所述:

对于服务器,其通信流程一般有如下步骤:

1. 调用 socket 函数创建 socket(侦听socket)
2. 调用 bind 函数 将 socket绑定到某个ip和端口的二元组上
3. 调用 listen 函数 开启侦听
4. 当有客户端请求连接上来后,调用 accept 函数接受连接,产生一个新的 socket(客户端 socket)
5. 基于新产生的 socket 调用 send 或 recv 函数开始与客户端进行数据交流
6. 通信结束后,调用 close 函数关闭侦听 socket

对于客户端,其通信流程一般有如下步骤:

1. 调用 socket函数创建客户端 socket
2. 调用 connect 函数尝试连接服务器
3. 连接成功以后调用 send 或 recv 函数开始与服务器进行数据交流
4. 通信结束后,调用 close 函数关闭侦听socket

上述流程可以绘制成如下图示:

tcp网络通信的基本流程

对于上面的图,读者可能有疑问,为什么客户端调用 close() ,会和服务器端 recv() 函数有关。

这个涉及到 recv() 函数的返回值意义,我们在下文中详细讲解。

服务器端实现代码:

/**
 * TCP服务器通信基本流程
 * zhangyl 2018.12.13
 */
#include <sys/types.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
int main(int argc, char* argv[])
{
    //1.创建一个侦听socket
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
    {
        std::cout << "create listen socket error." << std::endl;
        return -1;
    }
    //2.初始化服务器地址
    struct sockaddr_in bindaddr;
    bindaddr.sin_family = AF_INET;
    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bindaddr.sin_port = htons(3000);
    if (bind(listenfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
    {
        std::cout << "bind listen socket error." << std::endl;
        close(listenfd);
        return -1;
    }
 //3.启动侦听
    if (listen(listenfd, SOMAXCONN) == -1)
    {
        std::cout << "listen error." << std::endl;
        close(listenfd);
        return -1;
    }
    while (true)
    {
        struct sockaddr_in clientaddr;
        socklen_t clientaddrlen = sizeof(clientaddr);
  //4. 接受客户端连接
        int clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddrlen);
        if (clientfd != -1)
        {          
   char recvBuf[32] = {0};
   //5. 从客户端接收数据
   int ret = recv(clientfd, recvBuf, 32, 0);
   if (ret > 0) 
   {
    std::cout << "recv data from client, data: " << recvBuf << std::endl;
    //6. 将收到的数据原封不动地发给客户端
    ret = send(clientfd, recvBuf, strlen(recvBuf), 0);
    if (ret != strlen(recvBuf))
     std::cout << "send data error." << std::endl;
    else
     std::cout << "send data to client successfully, data: " << recvBuf << std::endl;
   } 
   else 
   {
    std::cout << "recv data error." << std::endl;
   }
   
   close(clientfd);
        }
    }
 
 //7.关闭侦听socket
 close(listenfd);
    return 0;
}

相关阅读

  • 网站如何建立才对 公司建立网站的步骤

    网站如何建立才对 公司建立网站的步骤

    今日IT小知识分享:网站如何建立才对和公司建立网站的步骤的相关介绍,接下来分享详细内容。 目前市面上有不少开源的CMS系统,可以快速搭建一个网站,但是延展性、安全性、功能适配性

  • tcp网络通信的基本流程 TCP网络通信流程概要

    tcp网络通信的基本流程 TCP网络通信流程概要

    跟大家聊一聊tcp网络通信的基本流程的相关经验,接下来就是全面介绍。 不管多么复杂的服务器或客户端程序,其网络通信的基本原理一定如下所述: 对于服务器,其通信流程一般有如下步骤

  • 网页设计排版框架怎么做 网站页面布局和样式设计

    网页设计排版框架怎么做 网站页面布局和样式设计

    一个电脑小知识,为大家介绍网页设计排版框架怎么做和网站页面布局和样式设计的IT小经验,一起跟随小编看看吧! 网页设计是创建网站流程中不可避免的策划工作,网页设计更是关切用户

  • Redis锁被别人释放解决办法

    Redis锁被别人释放解决办法

    一篇方法教程,与您分享Redis锁被别人释放解决办法的相关经验,接下来一起来看看吧。 什么是分布式锁? 要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。 线程锁:主要