Linux的socket通信

关于套接字通信定义如下:
套接字对应程序猿来说就是一套网络通信的接口,使用这套接口就可以完成网络通信。网络通信的主体主要分为两部分:客户端和服务器端。在客户端和服务器通信的时候需要频繁提到三个概念:IP、端口、通信数据,下面介绍一下需要注意的一些细节问题。

引用来源于:爱编程的大丙

在这里插入图片描述

服务器端的套接字通信流程:
(1)建立套接字,这个套接字就是一个文件描述符。


  • int lfd = socket();
  • 函数原型如下:
  • // 创建一个套接字
    int socket(int domain, int type, int protocol);

参数:
domain: 使用的地址族协议

  • AF_INET: 使用IPv4格式的ip地址
  • AF_INET6: 使用IPv4格式的ip地址
    type:
  • SOCK_STREAM: 使用流式的传输协议
  • SOCK_DGRAM: 使用报式(报文)的传输协议
  • protocol: 一般写0即可, 使用默认的协议
  • SOCK_STREAM: 流式传输默认使用的是tcp
  • SOCK_DGRAM: 报式传输默认使用的udp
    返回值:
  • 成功: 可用于套接字通信的文件描述符
  • 失败: -1
    函数的返回值是一个文件描述符,通过这个文件描述符可以操作内核中的某一块内存,网络通信是基于这个文件描述符来完成的。
    // 1. 创建监听的套接字int lfd = socket(AF_INET, SOCK_STREAM, 0);if(lfd == -1){perror("socket");exit(0);}

(2)绑定:将得到的监听的文件描述符和本地的IP 端口进行绑定


// 将文件描述符和本地的IP与端口进行绑定
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


  • 返回值:成功返回0,失败返回-1
    // 2. 将socket()返回值和本地的IP端口绑定到一起struct sockaddr_in addr;addr.sin_family = AF_INET;//系统存储的是小端端口,所以需要转换一下addr.sin_port = htons(10000);   // 大端端口,这里因为网络通信是使用的大端端口,// INADDR_ANY代表本机的所有IP, 假设有三个网卡就有三个IP地址// 这个宏可以代表任意一个IP地址// 这个宏一般用于本地的绑定操作addr.sin_addr.s_addr = INADDR_ANY;  // 这个宏的值为0 == 0.0.0.0,因为这个都是0000,不需要大小端转换int ret = bind(lfd, (struct sockaddr*)&addr, sizeof(addr));if(ret == -1){perror("bind");exit(0);}

(3) 设置监听


// 给监听的套接字设置监听
int listen(int sockfd, int backlog);


参数:

  • sockfd: 文件描述符, 可以通过调用socket()得到,在监听之前必须要绑定 bind()
  • backlog: 同时能处理的最大连接要求,最大值为128
    返回值:
  • 函数调用成功返回0,调用失败返回 -1
   // 3. 设置监听ret = listen(lfd, 128);if(ret == -1){perror("listen");exit(0);}

(4)阻塞并等待连接
会得到一个新的文件描述符(通信的)


// 等待并接受客户端的连接请求, 建立新的连接,
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);


返回值:函数调用成功,得到一个文件描述符, 用于和建立连接的这个客户端通信,调用失败返回 -1

    // 4. 阻塞等待并接受客户端连接struct sockaddr_in cliaddr;int clilen = sizeof(cliaddr);int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &clilen);if(cfd == -1){perror("accept");exit(0);}

(5)如果成功之后打印一条消息(可有可无)

    // 打印客户端的地址信息char ip[24] = {0};printf("客户端的IP地址: %s, 端口: %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ip, sizeof(ip)),ntohs(cliaddr.sin_port));

(6)开始通信

    // 5. 和客户端通信while(1){// 接收数据char buf[1024];memset(buf, 0, sizeof(buf));int len = read(cfd, buf, sizeof(buf));if(len > 0){printf("客户端say: %s\n", buf);write(cfd, buf, len);}else if(len  == 0){printf("客户端断开了连接...\n");break;}else{perror("read");break;}}

server.c

// server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main()
{// 1. 创建监听的套接字int lfd = socket(AF_INET, SOCK_STREAM, 0);if(lfd == -1){perror("socket");exit(0);}// 2. 将socket()返回值和本地的IP端口绑定到一起struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(10000);   // 大端端口// INADDR_ANY代表本机的所有IP, 假设有三个网卡就有三个IP地址// 这个宏可以代表任意一个IP地址// 这个宏一般用于本地的绑定操作addr.sin_addr.s_addr = INADDR_ANY;  // 这个宏的值为0 == 0.0.0.0int ret = bind(lfd, (struct sockaddr*)&addr, sizeof(addr));if(ret == -1){perror("bind");exit(0);}// 3. 设置监听ret = listen(lfd, 128);if(ret == -1){perror("listen");exit(0);}// 4. 阻塞等待并接受客户端连接struct sockaddr_in cliaddr;int clilen = sizeof(cliaddr);int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &clilen);if(cfd == -1){perror("accept");exit(0);}// 打印客户端的地址信息char ip[24] = {0};printf("客户端的IP地址: %s, 端口: %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ip, sizeof(ip)),ntohs(cliaddr.sin_port));// 5. 和客户端通信while(1){// 接收数据char buf[1024];memset(buf, 0, sizeof(buf));int len = read(cfd, buf, sizeof(buf));if(len > 0){printf("客户端say: %s\n", buf);write(cfd, buf, len);}else if(len  == 0){printf("客户端断开了连接...\n");break;}else{perror("read");break;}}close(cfd);close(lfd);return 0;
}

client.c

// client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main()
{// 1. 创建通信的套接字int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd == -1){perror("socket");exit(0);}// 2. 连接服务器struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(10000);   // 大端端口inet_pton(AF_INET, "10.0.2.15", &addr.sin_addr.s_addr);int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));if(ret == -1){perror("connect");exit(0);}// 3. 和服务器端通信int number = 0;while(1){// 发送数据char buf[1024];sprintf(buf, "你好, 服务器...%d\n", number++);write(fd, buf, strlen(buf)+1);// 接收数据memset(buf, 0, sizeof(buf));int len = read(fd, buf, sizeof(buf));if(len > 0){printf("服务器say: %s\n", buf);}else if(len  == 0){printf("服务器断开了连接...\n");break;}else{perror("read");break;}sleep(1);   // 每隔1s发送一条数据}close(fd);return 0;
}

在这里插入图片描述

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

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

相关文章

测试C#图像文本识别模块Tesseract的基本用法

微信公众号“dotNET跨平台”的文章《c#实现图片文体提取》&#xff08;参考文献3&#xff09;介绍了C#图像文本识别模块Tesseract&#xff0c;后者是tesseract-ocr&#xff08;参考文献2&#xff09; 的C#封装版本&#xff0c;目前版本为5.2&#xff0c;关于Tesseract的详细介绍…

马尔可夫链预测举例——钢琴销售的存贮策略

问题概述 一家钢琴专卖店&#xff0c;根据以往的销售经验&#xff0c;平均每周只能售出一架钢琴&#xff0c;现在经理指定的存贮策略是&#xff0c;每周末检查库存存量&#xff0c;仅当库存量为零时&#xff0c;才订购3架供下周销售&#xff1b;否则就不订购。试估计这种策略下…

pytest一些常见的插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff1…

数据库——理论基础

目录 1.1 什么是数据库 1.2 数据库管理系统&#xff08;DBMS&#xff09; 1.3 数据库和文件系统的区别 1.4 数据库的发展史 1.5常见的数据库 1.5.1关系型数据库 1.5.2 非关系型数据库 1.6 DBMS支持的数据模型 1.1 什么是数据库 数据&#xff1a;描述事物的符号记录 数…

opencv实现仿射变换和透射变换

##1&#xff0c; 什么是仿射变换&#xff1f; 代码实现 import numpy as np import cv2 as cv import matplotlib.pyplot as plt#设置字体 from pylab import mpl mpl.rcParams[font.sans-serif] [SimHei]#图像的读取 img cv.imread("lena.png")#仿射变换 row…

clickhouse简单安装部署

目录 前言(来源于官方文档)&#xff1a; 一.下载并上传 1.下载地址&#xff1a;点我跳转下载 2.上传至Linux 二.解压和配置 1.解压顺序 注意&#xff1a;必须按照以下顺序解压&#xff0c;并且每解压一个都要执行该解压后文件的install/doinst.sh文件 解压步骤&#xff…

Mycat管理及监控

Mycat管理 -h 是你自己的ip地址 相关命令及含义 Mycat-eye(图形化界面监控) 仅限于Linux系统

基于Xml方式Bean的配置-初始化方法和销毁方法

SpringBean的配置详解 Bean的初始化和销毁方法配置 Bean在被实例化后&#xff0c;可以执行指定的初始化方法完成一些初始化的操作&#xff0c;Bean在销毁之前也可以执行指定的销毁方法完成一些操作&#xff0c;初始化方法名称和销毁方法名称通过 <bean id"userService…

Spring Boot 日志文件

前言 本篇博客主要介绍自定义的日志打印、日志的级别高低、如何保存日志等等..... 一、日志是什么&#xff1f;日志有什么用&#xff1f; 日志就是我们控制台上输出的内容&#xff0c;控制台上的输出的信息就是日志信息&#xff0c;如下所示&#xff1a; 日志有什么用&#x…

【Vue2.0源码学习】生命周期篇-挂载阶段

文章目录 1. 前言2. 挂载阶段分析3. 总结 1. 前言 模板编译阶段完成之后&#xff0c;接下来就进入了挂载阶段&#xff0c;从官方文档给出的生命周期流程图中可以看到&#xff0c;挂载阶段所做的主要工作是创建Vue实例并用其替换el选项对应的DOM元素&#xff0c;同时还要开启对…

c语言基础知识+OS+数据结构

c语言&#xff1a; memory section&#xff1a; .bss&#xff1a; uninitialized or zero-initialized global and static variables .data: initialized global and static variables .text: Read only, code and const C语言编译流程&#xff1a; pre-compiler: …

在创业公司,我靠它续命 ...

不知不觉就在新公司工作了一周&#xff0c;没有想象中那么难受。创业公司里没有复杂的人际关系&#xff0c;也没有无聊的会议&#xff0c;更没有复杂的流程。每天上班第一件事就是开个小会&#xff0c;可能是站着开&#xff0c;也可能是连麦开。大家简单过一下前一天的进度&…

vue-cli创建项目、vue项目目录结(运行vue项目)、ES6导入导出语法、vue项目编写规范

vue-cli创建项目、vue项目目录结构、 ES6导入导出语法、vue项目编写规范 1 vue-cli创建项目 1.1 vue-cli 命令行创建项目 1.2 使用vue-cli-ui创建 2 vue项目目录结构 2.1 运行vue项目 2.2 vue项目的目录结构 3 es6导入导出语法 4 vue项目编写规范 4.1 修改项目 4.2 以后…

LabVIEW崩溃后所产生的错误日志文件的位置

LabVIEW崩溃后所产生的错误日志文件的位置 LabVIEW开发环境刚刚崩溃&#xff0c;请问我如何访问崩溃后自动生成的日志文件&#xff1f; LabVIEW崩溃后产生的转储文件位于何处&#xff1f; 代码导致了LabVIEW崩溃&#xff0c;请问哪些文件可以帮助NI技术支持了解具体原因&…

腾讯mini项目-【指标监控服务重构】2023-08-24

今日已办 Jeager 功能 监控分布式工作流程并排除故障识别性能瓶颈追踪根本原因分析服务依赖关系 部署 部署 Deployment — Jaeger documentation (jaegertracing.io) 支持 clickhouse jaegertracing/jaeger-clickhouse: Jaeger ClickHouse storage plugin implementation …

Python之列表

标题 列表什么是列表列表的创建列表的删除列表的访问 列表的常用方法append()、insert()、extend()pop()、remove()、clear()count()、index()list()、 filter()、 reduce()、lambda() 列表支持的运算加法运算符乘法运算符*成员测试运算符in 内置函数对列表的操作列表推导式列表…

Python 逢七拍手小游戏2.0

"""逢七拍手游戏介绍&#xff1a;逢七拍手游戏的规则是&#xff1a;从1开始顺序数数&#xff0c;数到有7&#xff0c;或者是7的倍数时&#xff0c;就拍一手。例如&#xff1a;7、14、17......70......知识点&#xff1a;1、循环语句for2、嵌套条件语句if/elif/e…

tensorrt获取输入输出

利用Netron打开onnx&#xff0c;右边名字&#xff1a; int input_index engine->getBindingIndex("inout1.1");int output_index engine->getBindingIndex("191");

010_第一代软件开发(二)

第一代软件开发(二) 文章目录 第一代软件开发(二)项目介绍界面布局功能完善快照功能获取可用串口播放按键提示音 关键字&#xff1a; Qt、 Qml、 QSerialPort、 QPixmap、 QSoundEffect 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff…

Java基础(一)——Hello World,8种数据类型,键盘录入

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…