C语言实现TCP通信

2023-05-16

如果想要自己写一个服务器和客户端,我们需要掌握一定的网络编程技术,个人认为,网络编程中最关键的就是这个东西——socket(套接字)。socket(套接字):简单来讲,socket就是用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

TCP协议

TCP协议:是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。

关键词:三次握手,可靠,基于字节流。

可能有朋友会问,TCP就这么简单一句话吗?当然不是,TCP作为非常重要的传输协议,细节知识是很多的,细讲起来这一篇文章怕是不够。不过在本篇内容中,我们只需了解他的几个关键词特性,就能很好的理解下面的内容。

C语言实现TCP通信C语言实现TCP通信

TCP服务器端和客户端的运行流程

如图,这是一个完整的TCP服务器——客户端的运行流程图,其实我个人认为程序啊,不管哪个语言都是一样,核心就在于算法的设计和函数的调用。那么图中的函数都是什么意思呢?

1.创建socket

socket是一个结构体,被创建在内核中


sockfd=socket(AF_INET,SOCK_STREAM,0); //AF_INT:ipv4, SOCK_STREAM:tcp协议  

2.调用bind函数

将socket和地址(包括ip、port)绑定。

需要定义一个结构体地址,以便于将port的主机字节序转化成网络字节序


struct sockaddr_in myaddr; //地址结构体 
  

bind函数


bind(sockfd,(struct sockaddr*)&myaddr,sizeof(serveraddr))
  

3.listen监听,将接收到的客户端连接放入队列


listen(sockfd,8) //第二个参数是队列长度
  

4.调用accept函数,从队列获取请求,返回socket描 述符

如果无请求,将会阻塞,直到获得连接


int fd=accept(sockfd, NULL,NULL);//这边采用默认参数
  

5.调用read/write进行双向通信

6.关闭accept返回的socket


close(scokfd); 
  

下面放出完整代码


/*服务器*/ 
#include  
#include  
#include  
#include  
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
int main() 
{ 
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建套接字 
    if (sockfd < 0) { perror("socket"); return -1; } //创建失败的错误处理 printf("socket..............\n"); //成功则打印“socket。。。。” struct sockaddr_in myaddr; //创建“我的地址”结构体 memset(&myaddr, 0, sizeof(myaddr)); //对内存清零(保险起见) myaddr.sin_family = AF_INET; //选择IPV4地址类型 myaddr.sin_port = htons(8888); //选择端口号 myaddr.sin_addr.s_addr = inet_addr("192.168.3.169"); //选择IP地址 if (0 > bind(sockfd, (struct sockaddr*)&myaddr, sizeof(myaddr)))//绑定套接字 
    { 
        perror("bind"); 
        return -1; 
    } 
    printf("bind..........\n"); 
  
    if (0 > listen(sockfd, 8))//调用listen对指定端口进行监听 
    { 
        perror("listen"); 
        return -1; 
    } 
    printf("listen............\n"); 
     
    int connfd = accept(sockfd, NULL, NULL);//使用accept从消息队列中获取请求 
    if (connfd < 0) { perror("accept"); return -1; } printf("accept..............\n"); char buf[100];//定义一个数组用来存储接收到的数据 int ret; while (1) { memset(buf, 0, sizeof(buf)); ret = read(connfd, buf, sizeof(buf)); if (0 > ret) 
        { 
            perror("read"); 
            break; 
        }//执行while循环读取数据,当 
        else if (0 == ret) 
        { 
            printf("write close!\n"); 
            break; 
        } 
        printf("recv: "); 
        fputs(buf, stdout);//打印接收到的数据 
    } 
    close(sockfd);//关闭套接字 
    close(connfd);//断开连接 
    return 0; 
} 
/*客户端*/(具体功能和服务器一样,所以不再加注释) 
#include  
#include  
#include  
#include  
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
int main() 
{ 
 int sockfd; 
    if (0 > (sockfd = socket(AF_INET, SOCK_STREAM, 0))) 
    { 
        perror("socket"); 
        return -1; 
    } 
    printf("socket...........\n"); 
     
    struct sockaddr_in srv_addr; 
    memset(&srv_addr, 0, sizeof(srv_addr)); 
    srv_addr.sin_family         = AF_INET; 
    srv_addr.sin_port           = htons(8888); 
    srv_addr.sin_addr.s_addr    = inet_addr("192.168.3.169"); 
    if (0 > connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr))) 
    { 
        perror("connect"); 
        return -1; //exit //pthread_exit 
    } 
    printf("connect..............\n"); 
    char buf[100]; 
    int ret; 
    while (1) 
    { 
        printf("send: "); 
        fgets(buf, sizeof(buf), stdin); 
        ret = write(sockfd, buf, sizeof(buf)); 
        if (ret < 0) 
        { 
            perror("write"); 
            break; 
        } 
        if (strncmp(buf, "quit", 4) == 0) 
            break; 
    } 
    close(sockfd); 
    return 0; 
}   

干货:《Linux就该这么学》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言实现TCP通信 的相关文章

  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • ZeroMQ可以用来接受传统的套接字请求吗?

    我正在尝试使用 ZeroMQ 重写我们的旧服务器之一 现在我有以下服务器设置 适用于 Zmq 请求 using var context ZmqContext Create using var server context CreateSoc
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • iOS 上的多个 HTTP 请求与单个 TCP 连接

    我正在开发一个 iPhone 应用程序 它使用我控制的基于 Web 的 API 连接到持续打开的 TCP 端口并通过 TCP API 发出请求 或者为我想要获取的所有数据发出新的 HTTP 请求 会更快或更高效吗 我认为差异可以忽略不计 但
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 触发“对等方重置连接”

    我想测试当发生 对等方重置连接 错误时我们的应用程序 嵌入式 ftp 服务器 中发生的日志记录 这个帖子 https stackoverflow com questions 1434451 connection reset by peer很
  • 中断 Select 以添加另一个要在 Python 中监视的套接字

    我正在 Windows XP 应用程序中使用 TCP 实现点对点 IPC 我正在使用select and socketPython 2 6 6 中的模块 我有三个 TCP 线程 一个读取线程通常会阻塞select 一个通常等待事件的写入线程
  • 套接字编程-listen() 和accept() 有什么区别?

    我一直在读本教程 http www cs rpi edu moorthy Courses os98 Pgms socket html了解套接字编程 看来listen and accept 系统调用都做同样的事情 即阻塞并等待客户端连接到使用
  • 使用 InputStream 通过 TCP 套接字接收多个图像

    每次我从相机捕获图像时 我试图将多个图像自动从我的 Android 手机一张一张地发送到服务器 PC 问题是read 函数仅在第一次时阻塞 因此 从技术上讲 只有一张图像被接收并完美显示 但在那之后当is read 回报 1 该功能不阻塞
  • C#:如何在 Socket.BeginReceive 回调之前终止套接字?

    我有一个接收来自客户端的连接请求的服务器 该服务器使用异步Socket BeginReceive and Socket EndReceive方法 该代码与找到的代码非常相似here http msdn microsoft com en us
  • TCP 连接寿命

    客户端 服务器 TCP 连接在野外可以持续多长时间 我希望它保持永久连接 但事情发生了 所以客户端将不得不重新连接 我什么时候可以说代码有问题而不是某些外部设备有问题 我同意赞 林克斯的观点 虽然无法保证 但假设不存在连接或带宽问题 您可以
  • Java Servlet 中限制 HTTP 请求

    在 java servlet 中 如何根据客户端的 IP 地址限制来自用户的 http 请求 我不想每秒处理来自特定源 IP 地址的超过 X 个请求 其中 X 是可配置的并且具有 0 1 中的实际值 10 范围 从 10 秒内 1 个请求到
  • Docker 容器是否有自己的 TCP/IP 堆栈?

    我试图了解来自连接到主机的线路并定向到 Docker 容器内的应用程序的网络数据包在幕后发生了什么 如果它是一个经典的 VM 我知道到达主机的数据包将由虚拟机管理程序 例如 VMware VBox 等 传输到 VM 的虚拟 NIC 并从那里
  • iPhone 上的 TCP 打洞

    我已经阅读了一些内容 虽然我是 iPhone 网络的新手 但我想知道 TCP 打孔是否可以通过 NAT 连接两台 iPhone 我还阅读了一些有关 uPnP 和发夹的有用内容 但我根本不熟悉这些内容 所以如果有人对这是否可能有任何想法 我的
  • NodeJS:TCP套接字服务器仅在第一次返回数据

    我正在尝试在 node js 中编写一个小型中继脚本 用于侦听本地套接字上传入的 TCP 连接 当它收到连接时 将流量转发给第三方 它还必须从该第三方获取任何返回的数据并将其发送回原始本地套接字 我试过类似的代码http delog wor
  • 服务器套接字在 Close_Wait 中挂起

    场景如下 我正在从 C 服务器应用程序向客户端发送大量数据 突然数据流停止 客户端没有数据更新并且端口被阻塞 发生这种情况时 服务器端症状是 Close Wait 在该端口 netstat 操作将在日志中阻塞 错误代码 135 无法从客户端
  • PHP 通过 TCP/IP 发送消息

    我尝试通过 TCP IP 从 PHP 网站向 Arduino 发送消息 使用以下代码我可以从 php 网站发送消息 问题是 当第一次调用该网站时 消息不会立即发送 网站刷新几次后 消息就会到达 但逻辑上很多次 就像网站刷新量一样 已经尝试将
  • 在本地主机上使用相同的 IP 和端口创建套接字

    我在 Linux 上看到奇怪的行为 我看到远程端和本地端都显示相同的 IP 和端口组合 以下是 netstat 输出 netstat anp 网络统计grep 6102 tcp 0 0 139 185 44 123 61020 0 0 0
  • 如何才能将 TCP 连接返回到同一端口?

    机器是 RHEL 5 3 内核 2 6 18 有时我在 netstat 中注意到我的应用程序有连接 建立了 TCP 连接本地地址 and 国外地址是一样的 其他人也报告了同样的问题 症状与链接中描述的相同 客户端连接到本地运行的服务器的端口

随机推荐

  • 我对onSizeChange方法的源码解析

    如果当前的自定义控件是继承ViewGroup xff0c 那么在ViewGroup重写的layout方法中 xff1a 可知调用父类也就是View的layout方法 再看View的layout方法 xff1a 查看设置自己坐标的setFra
  • 5 个你不知道的关于 Python 类的技巧

    5 个你不知道的关于 Python 类的技巧 1 创建 一个 常量值2 多个类构造函数3 创建枚举4 迭代器5 以列表的形式访问一个类 Python 有许多强大的特性 xff0c 在处理类时提供了极大的灵活性 在这里 xff0c 我将向您展
  • 激光雷达和RTK的标定(无人小车)

    总结一下最近的标定工作 xff0c 标定平台是实验室的无人小车 xff0c 目标是实现激光雷达 lidar 和RTK的标定 xff0c 也就是求解lidar到RTK的位姿变换矩阵 采用的代码是ETH的lidar align https gi
  • 虚拟机安装Ubuntu20.04 + VCS2018

    虚拟机安装Ubuntu20 04 43 VCS2018 前言正文1 准备内容Vmware Workstation 16 prounbuntu 20 04 安装包vcs 43 scl 43 verdi等安装包 2 Ubuntu系统的安装ope
  • input里面file实现上传图片及预览功能

    在这里插入简单的HTML代码片 lt form action 61 34 34 gt 文件 xff1a lt input type 61 34 file 34 name 61 34 myFile 34 id 61 34 myFile 34
  • 创建ROS-wrapper

    创建ROS wrapper 对高博的ygz stereo inertial的开源算法添加ROS node源文件的编写CMakeLists文件的编写分目录下的CMakeLists完整CMakeLists路径 home fei devv ygz
  • 新买了块翼联的AX200的网卡,结果开移动热点的时候遇到了点问题

    买网卡这事的起因要从入手了switch说起 xff0c 直连网不是不能用 xff0c 就是太难用了 xff0c 下载个东西要几十个小时 xff0c 玩个马造2连地图都下载不了 然后试用了3天的网易uu加速器 xff0c 好用是真的好用 xf
  • HDU 1085(Holding Bin-Laden Captive!)

    题意 xff1a 有三种价值分别为 1 2 5 的硬币 xff0c 每一种分别由 a b c 个 xff0c 求这些硬币不能组成的最小价值 分析 xff1a 生成函数板子题 xff08 贴一个讲生成函数的链接https blog csdn
  • 大电流的走线和过孔

    工程师在设计的时候 xff0c 很容易忽略走线宽度的问题 xff0c 因为在数字设计时 xff0c 走线宽度不在 考虑范围里面 通常情况下 xff0c 都会尝试用最小的线宽去设计走线 xff0c 这时 xff0c 在大电流时 xff0c 将
  • c++ 实现基本数据结构代码

    数据结构是计算机科学的一个重要的分支 xff0c 主要研究如何有效地存储和组织数据以便于快速访问和操作 常见的数据结构有 xff1a 数组 xff1a 是一种线性的数据结构 xff0c 可以通过索引来访问数组中的元素 链表 xff1a 是一
  • Jetson开发实战记录(二):Jetson Xavier NX版本区别以及烧录系统

    Jetson开发实战记录 xff08 二 xff09 xff1a Jetson Xavier NX版本区别以及烧录系统 一 Jetson Xavier NX类型1 SD卡槽的版本 xff08 官方版本 xff09 2 带eMMC存储芯片的版
  • ZYNQ7000(AX7020)移植Linux操作系统(二):u-boot的编译和启动

    总述 我们已经在 PC 上已经安装了 Ubuntu 客户操作系统 xff0c 以及在 Ubuntu 操作系统里安装了 SDK 2015 4 工具 要想在 Zynq 平台上运行 Ubuntu 操作系统 xff0c 必项预先制作作镜像文件 xf
  • 10个让你的 Python 代码更具 pythonic 风格的示例

    10个让你的 Python 代码更具 pythonic 风格的示例 1 变量交换 2 函数返回元组 xff08 自动打包 解包 xff09 3 多重比较 4 多重比较 5 列表推导式 6 将 Python 字典当做缓存 7 关键字参数 8
  • 进程的调度算法

    先来先服务调度算法 xff1a 先来先服务调度算法是一种最简单的调度算法 xff0c 也称为先进先出或严格排队方案 当每个进程就绪后 xff0c 它加入就绪队列 当前正运行的进程停止执行 xff0c 选择在就绪队列中存在时间最长的进程运行
  • 华为云服务器购买及使用指南

    前言 作者参与牛客网的买服务器返现活动 xff0c 以某个奇妙的价格价格购入了一个一年的华为云服务器 xff0c 具体多少钱就不透露了 xff0c 不然会被当作广告性能参数如下 xff1a 购买 偶然看到这个活动 xff0c 然后点进去 x
  • JS 简单的事件

    实现鼠标滑过按钮时显示文本 xff0c 滑出时隐藏文本 span class token doctype lt DOCTYPE html gt span span class token tag span class token tag s
  • 在ROS中实现darknet_ros(YOLO V3)检测以及训练自己的数据集

    目录 1 darknet ros介绍 2 darknet ros原始项目编译测试 3 yolov3训练自己的数据集 4 使用自己训练好的数据集 1 darknet ros介绍 Darknet概述 https blog csdn net u0
  • apache options index 设置问题

    禁止显示Apache目录列表 Indexes FollowSymLinks 如何修改目录的配置以禁止显示Apache 目录列表 缺省情况下如果你在浏览器输入地址 xff1a http localhost 8080 如果你的文件根目录里有in
  • Centos7.7安装vncserver虚拟网络控制台

    虚拟网络控制台 xff08 VNC xff09 是一个图形桌面共享软件 xff0c 允许您使用键盘和鼠标远程控制另一台计算机 系统环境 服务端 xff1a Centos7 7 Minimal客户端 xff1a Windows10客户端VNC
  • C语言实现TCP通信

    如果想要自己写一个服务器和客户端 xff0c 我们需要掌握一定的网络编程技术 xff0c 个人认为 xff0c 网络编程中最关键的就是这个东西 socket 套接字 socket 套接字 xff1a 简单来讲 xff0c socket就是用