在Linux系统上实现TCP(socket)通信

news2024/11/24 7:08:36

一.什么TCP

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

二.TCP通信流程

三. TCP 服务器端  

1 创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM tcp通信

2 绑定(bind)
struct sockaddr_in myaddr;
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(8888);
myaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY 自动提取本机ip地址
bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr));

3 监听 (设置允许同时连接的客户端的最大值 同时连接:已经连上的,不算同时连接)
int listen(int sockfd, int backlog);
listen(sockfd, 5);

4 阻塞等待连接 accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
sockfd :socket 的返回值
addr :客户端的ip地址和端口号存在addr中 (通常为NULL)//udp recvfrom倒数第二个参数一
样
addrlen :客户端的ip地址和端口号长度 (通常为NULL)//udp recvfrom倒数第一个参数一样
返回值(重点)
是一个newfd :(一个新的fd,此fd用来标识客户端,第一个连接的 4,下一个5,....)

5 接收数据 (阻塞接收)
ssize_t recv(int newfd, void *buf, size_t len, int flags);
参数: newfd accept的返回值, newfd
buf 接收的数据存放的位置
len 将要接收的数据的长度
flags 暂时为0
返回值: 实际接收的数据的长度,如果<=0,则证明客户端已经断开连接

6 发送数据
ssize_t send(int newfd, const void *buf, size_t len, int flags);
参数: newfd accept的返回值, newfd
buf 发送数据首地址
len 发送数据长度
flags 暂时为0
返回值: 实际发送的数据的长度

7 关闭socket
close(newfd);
close(fd);
实例 :
server.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(8888);
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY 得到当前计算机的ip地址
    int ret = bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr));
    printf("ret %d\n",ret);

    listen(fd, 5);

    int newfd = accept(fd, NULL, NULL); //等待客户端连接

    char buf[100] = { 0 };
    ret = recv(newfd, buf, sizeof(buf), 0); //newfd 代表连接的客户端
    printf("ret %d, newfd is %d, buf is %s\n",ret, newfd, buf);

    close(newfd);
    close(fd);
}
执行:gcc hello.c -o server      ./server
另外起一个终端,执行:nc 127.0.0.1 8888 ( 模拟出一个客户端 ),在这里发送信息,服务器端就会收到信息。

四. TCP 客户端

1 创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM tcp通信 

2 连接服务端
struct sockaddr_in youaddr;
youaddr.sin_family = AF_INET;
youaddr.sin_port = htons(8888);
youaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd socket的返回值
addr 保存对方的ip地址和端口
addrlen sizeof(youaddr);
返回值:成功 返回0 失败返回 -1
一旦连接成功,服务端解除阻塞(accpet)

3 发送数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数:
sockfd socket的返回值
buf 发送的数据存放的位置,
len 发送的数据的长度(以字节为单位)
flags 暂时为0

4 接收数据 //同样用recv()

5 关闭socket
close(fd);
实例 :
client.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in youaddr;
    youaddr.sin_family = AF_INET;
    youaddr.sin_port = htons(8888);
    youaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    connect(fd, (struct sockaddr *)&youaddr, sizeof(youaddr));

    char buf[] = "hello";
    send(fd, buf, sizeof(buf), 0);

    close(fd);
}
执行:gcc hello.c -o client      ./client      
另外起一个终端,执行:nc -l 8888(模拟服务器)
之后在执行./client的终端就可以给模拟的服务器发消息了。

五.练习

  实现服务器端循环收数据打印,客户端从 main函数的 参数中提取 ip 地址和端口号 , 可以循环从键盘输入数据,发数据, 如果客户端输入 ‘0’ ,则客户端退出。
server.c   (服务器端)
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(8888);
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY 得到当前计算机的ip地址
    int ret = bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr));
    listen(fd, 5);
    int newfd = accept(fd, NULL, NULL); //等待客户端连接
    while(1)
    {
        char buf[100] = { 0 };
        if(recv(newfd, buf, sizeof(buf), 0) > 0) //newfd 代表连接的客户端
        printf("buf is %s\n", buf);
        else
        break;
    }
    close(fd);
}

client.c   (客户端)

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in youaddr;
    youaddr.sin_family = AF_INET;
    youaddr.sin_port = htons(atoi(argv[2]));
    youaddr.sin_addr.s_addr = inet_addr(argv[1]);
    connect(fd, (struct sockaddr *)&youaddr, sizeof(youaddr));
    char buf[100] = "hello";
    while(1)
    {
        gets(buf);
        if (buf[0] =='0')
        {
            break;
        }
        send(fd, buf, sizeof(buf), 0);
    }
    close(fd);
}

起两个终端一个执行服务器,一个执行客户端。

一个执行:gcc hello.c -o server      ./server

另一个执行:gcc hello.c -o client      ./client    192.168.133.5    8080     
//这里需要输入你的本地IP地址和端口号
这样客户端就能发送消息给服务器,服务器能一直接收消息。(实测成功)

六. 结语

     这就是TCP套接字在Linux上使用的方法与步骤,本次的代码分享到此结束,感谢大家观看,希望大家点点赞,点点关注,后续还会发Linux系统上的TCP并发服务器(服务器能同时连多个客户端),谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1581374.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

.net 6 集成NLog

.net 6 webapi项目集成NLog 上代码step 1 添加nugetstep 2 添加支持step 3 添加配置文件 结束 上代码 step 1 添加nuget 添加nuget 包 Roc step 2 添加支持 修改program.cs var builder WebApplication.CreateBuilder(args); // 添加NLog日志支持 builder.AddRocNLog();ste…

UDP简单总结

UDP&#xff1a;用户数据报协议 特点: 无连接、不可靠通信 不事先建立连接&#xff0c;数据按照包发&#xff0c;一包数据包含&#xff1a;自己的IP、程序端口、目的地IP、程序端口和数据(限制在64KB内) 发送方不管对方是否在线&#xff0c;数据在中间丢失也不管&#xff0c;…

用友NC Cloud importhttpscer接口存在任意文件上传漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 用友NC Cloud 是基于云计算技术的企业管理软件。它提…

监控指标体系:交互延迟上的探索与最佳实践

FID 在互联网高速发展的时代,用户体验已成为企业竞争的关键所在。网页性能作为用户体验的重要组成部分,直接影响着用户的满意度和工作效率。First Input Delay(FID)作为衡量网页性能的重要指标,越来越受到业界关注。今天,让我们一起来深入了解FID,探讨如何优化FID以提升…

GitHub 仓库 (repository) Pulse - Contributors - Network

GitHub 仓库 [repository] Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津&#xff0c;还是在火热地开发之中&#xff0c;从这里可以一目了然。 2. Contributors 显示对该仓库进…

51单片机之LED点阵屏

目录 1.LED点阵屏简介 2.配置LED点阵屏代码 1.LED点阵屏简介 LED点阵屏真的是遍布我们我们生活的每个角落&#xff0c;从街边的流动显示字的招牌到你的液晶显示屏&#xff0c;都是基于点阵屏的原理研究出来的。还有那个世界上最大的球状建筑物&#xff1a;MSG Sphere&#xff…

签名失败当前系统没有安装苹果根证书

发生背景 第一次我没有iOS证书(.p12)和描述文件(.mobileprovision)。按照这个文档https://ask.dcloud.net.cn/article/152拿到后&#xff0c;安心打包出问题。 错误信息 [Info] begin getCertCName... [Info] begin codesignFramwork to ipa... [Error] DCUniBase.framework…

Mac 安装 brew brew cask 遇到的问题以及解决办法

安装Homebrew和Homebrew Cask是在Mac上管理软件包的常用方法。虽然大多数情况下安装这两个工具是比较简单的&#xff0c;但有时候也可能遇到一些问题。下面是一些常见的问题以及解决办法&#xff1a; 问题1&#xff1a;无法安装Homebrew 解决办法&#xff1a; 1.确保你的Mac已连…

跟TED演讲学英文:Why AI will spark exponential economic growth by Cathie Wood

TED英文文稿 文章目录 TED英文文稿Why AI will spark exponential economic growthIntroductionVocabularyTranscriptSummary Why AI will spark exponential economic growth Link: https://www.ted.com/talks/cathie_wood_why_ai_will_spark_exponential_economic_growth? …

打印CSDN博客只需两步

打印博客 关闭浏览器限制 浏览器打开对应博客&#xff0c;F12&#xff0c;在console下粘贴如下代码&#xff0c;回车 (function doPrint(){var head_str "<html><head><title></title></head><body>"; var foot_str "&…

three.js跟着教程实现VR效果(四)

参照教程&#xff1a;https://juejin.cn/post/6973865268426571784&#xff08;作者&#xff1a;大帅老猿&#xff09; 1.WebGD3D引擎 用three.js &#xff08;1&#xff09;使用立方体6面图 camera放到 立方体的中间 like “回” 让贴图向内翻转 &#xff08;2&#xff09;使…

【机器学习—聚类】

文章目录 1、前言1.1、定义1.2、数据 2、亲和力传播3、聚合聚类4、BIRCH5、DBSCAN6、K-均值7、Mini-Batch K-均值8、均值漂移聚类9、OPTICS10、光谱聚类11、高斯混合模型12、参考 1、前言 1.1、定义 聚类分析&#xff0c;即聚类&#xff0c;是一项无监督的机器学习任务。它包…

本地开发nginx代理服务器

1、nginx 解释 nginx 是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP 代理服务器。 在性能上&#xff0c;Nginx占用很少的系统资源&#xff0c;能支持更多的并发连接&#xff0c;达到更高的访问效率&#xff1b; 在功能上&#xff0c;Nginx是优…

番茄 abogus rpc调用

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章…

SpringMVC:搭建第一个web项目并配置视图解析器

&#x1f449;需求&#xff1a;用spring mvc框架搭建web项目&#xff0c;通过配置视图解析器达到jsp页面不得直接访问&#xff0c;实现基本的输出“hello world”功能。&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb; 1 创建web项目 1…

web安全学习笔记【22】——文件上传(1)

WEB攻防-PHP应用&文件上传&函数缺陷&条件竞争&二次渲染&黑白名单&JS绕过 演示案例&#xff1a; PHP-原生态-文件上传-前后端验证PHP-原生态-文件上传-类型文件头验证PHP-原生态-文件上传-后缀黑白名单验证PHP-原生态-文件上传-解析配置&二次渲染…

网页布局与样式设计:从简单到复杂

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一. 基础布局技巧 1.使用CSS Grid布局设计网页布局 1.1 创建网格容器 1.2. 定义…

GridView控件的使用(一)

GridView控件通常用于在Windows窗体或Web应用程序中显示数据表格。它是一个强大的数据绑定控件&#xff0c;能够灵活地显示和编辑数据源中的数据。 在何种情况下应使用GridView进行绑定控件&#xff1a; 显示结构化数据&#xff1a;当您需要展示一系列具有相同字段的数据记录…

Go语言中的互斥锁(Mutex)和读写锁(RWMutex)

Mutex Mutex结构体 type Mutex struct {state int32 //表示互斥锁的状态,比如是否被锁定等sema uint32 //表示信号里,协程阻塞等待的信号量,解锁的协程释放信号量从而唤醒等待信号量的协程 } Locked: 表示Mutex是否已被锁定(1表示已经被锁定)Woken: 表示是否有协程被唤醒(1已有…

【JVM】面试题汇总

JVM1. 什么是JVM&#xff1f;2. 了解过字节码文件的组成吗&#xff1f;3. 什么是运行时数据区4. 哪些区域会出现内存溢出5. JVM在JDK6-8之间在内存区域上有什么不同 6. 类的生命周期 7. 什么是类加载器&#xff1f;类加载器有哪几种 8. 什么是双亲委派机制&#xff1f;有什么好…