基于TCP的服务器端/客户端

2023-11-16

TCP服务器端默认函数调用顺序

  1. socket():创建socket
  2. bind():分配socket地址
  3. listen():等待连接请求状态
  4. accept():允许连接
  5. read() / write():数据交换
  6. close():断开连接

等待连接请求状态

int listen(int sock, int backlog);

  • 成功时返回0, 失败时返回-1
  • sock:服务器端套接字
  • backlog:连接请求等待队列的长度

受理客户端连接请求

服务器端套接字是做门卫的,与客户端交换数据需要另外一个套接字,这个套接字由accept()函数自动创建。
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);

  • 成功时返回创建的套接字文件描述符,失败时返回-1
  • sock:服务器端套接字的文件描述符
  • addr:发起连接的客户端的地址信息
  • addrlen:addr的长度地址

TCP客户端默认函数调用顺序

  1. socket():创建套接字
  2. connect():请求连接
  3. read() / write():交换数据
  4. close():断开连接

请求连接

int connect(int sock, struct sockaddr *servaddr, socklen_t addrlen);

  • 成功时返回0, 失败时返回-1
  1. 客户端的IP地址和端口在调用connect()自动分配;
  2. 客户端调用connect()后,只有在服务器端接受连接请求或者发生断网等异常情况时才会返回;
  3. 服务器端接受到了客户端的connect信息,并不会立即进行数据交换,而是把连接请求信息记录到等待队列;
  4. 客户端只有等到服务器端调用listen()后才能调用connect()函数;
  5. 在客户端调用connect()前,如果服务器端调用accept()函数,则进入阻塞(blocking)状态,直到客户端调用connect为止。

实现迭代服务器端/客户端

服务器端/客户端源码

echo_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF_SIZE 1024

void error_handling(char* message);

int main(int argc, char* argv[]) {
	int serv_sock, clnt_sock;
	char message[BUF_SIZE];
	int str_len, i;

	struct sockaddr_in serv_adr, clnt_adr;
	socklen_t clnt_adr_sz;

	if (argc != 2) {
		printf("Usage: %s <port> \n", argv[0]);
		exit(1);
	}

	serv_sock = socket(PF_INET, SOCK_STREAM, 0);
	if (serv_sock == -1) {
		error_handling("socket() error");
	}

	memset(&serv_adr, 0, sizeof(serv_adr));
	serv_adr.sin_family = AF_INET;
	serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_adr.sin_port = htons(atoi(argv[1]));

	if (bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) {
		error_handling("bind() error");
	}

	if (listen(serv_sock, 5) == -1) {
		error_handling("listen() error");
	}

	clnt_adr_sz = sizeof(clnt_adr);
	for (i = 0; i < 5; ++i) {
		clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
		if (clnt_sock == -1) {
			error_handling("accept() error");
		}
		else {
			printf("Connected client %d \n", i + 1);
		}
		while ((str_len = read(clnt_sock, message, BUF_SIZE)) != 0) {
			write(clnt_sock, message, str_len);
		}
		close(clnt_sock);
	}

	close(serv_sock);

	return 0;
}


void error_handling(char* message) {
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

echo_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF_SIZE 1024

void error_handling(char* message);

int main(int argc, char* argv[]) {
	int sock;
	char message[BUF_SIZE];
	int str_len, recv_len, recv_cnt;

	struct sockaddr_in serv_adr;

	if (argc != 3) {
		printf("Usage: %s <IP>  <port> \n", argv[0]);
		exit(1);
	}

	sock = socket(PF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		error_handling("socket() error");
	}

	memset(&serv_adr, 0, sizeof(serv_adr));
	serv_adr.sin_family = AF_INET;
	serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
	serv_adr.sin_port = htons(atoi(argv[2]));

	if (connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) {
		error_handling("connect() error");
	}
	else {
		puts("Connected...............");
	}

	while (1)
	{
		fputs("Input message(Q to quit): ", stdout);
		fgets(message, BUF_SIZE, stdin);
		if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) {
			break;
		}

		str_len = write(sock, message, strlen(message));
		recv_len = 0;

		while (recv_len < str_len) {
			recv_cnt = read(sock, &message[recv_len], BUF_SIZE - 1);
			if (recv_cnt == -1) {
				error_handling("read() error!");
			}
			recv_len += recv_cnt;
		}
		message[recv_len] = 0;
		printf("Message from server: %s", message);
	}

	close(sock);

	return 0;
}

void error_handling(char* message) {
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

运行命令

// run echo_server.c
gcc echo_server.c -o eserver
./eserver 9190

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

基于TCP的服务器端/客户端 的相关文章

  • 服务器超线程的好处

    服务器超线程的好处 1 提高性能 超线程通过提高整体系统吞吐量显着提高服务器性能 通过允许多个线程在单个物理内核上同时执行 超线程减少了空闲时间并最大限度地利用了可用资源 这会加快任务执行速度并缩短应用程序的响应时间 尤其是在多线程工作负载
  • 网络安全现状:揭秘白帽黑客的真实收入

    前言 作为一个网络安全行业五年打工仔 今天就来看看黑客的收入和方向怎么样 一个黑客年薪是多少呢 外界普遍认为黑客是高收入群体 那么你想过黑客是怎么获得收入的吗 黑客分为白帽黑客和黑帽黑客 处于黑白两道的黑客会的技术都有些相似 但是却是对立的
  • 虚拟主机操作系统 Windows、Linux

    操作系统将直接影响服务器的性能 安全性和可用性 因此确保选择合适的操作系统对于成功运行您的网站或应用程序至关重要 以下是一些考虑因素 可帮助您选择适合您需求的虚拟主机操作系统 1 熟悉度和技术支持 如何选择操作系统应该考虑您的经验水平和熟悉
  • 网络空间安全女生就业,怎么学?

    我实验室的学长们基本都是以红队和复现为主 如果学校好点可能还有更多的选择 如果想在这个方向深入下去 推荐流程是先打两年CTF 把大概的技术方向摸一摸 大一的话 如果学校还不错 那就优先建议打好基础 包括C语言 Python一类 建议把CTF
  • centos系统有什么好处?

    CentOS是一种基于开源代码的Linux操作系统 它有以下几个优势 1 稳定性 CentOS是一种非常稳定的操作系统 它的代码经过了严格的测试和审查 因此它非常适合作为服务器操作系统使 用 2 安全性 由于CentOS是基于开源代码的操作
  • 掌握内网渗透之道,成为实战高手,看《内网渗透实战攻略》就够了

    文末送书 文末送书 今天推荐一本网络安全领域优质书籍 内网渗透实战攻略 文章目录 前言 如何阅读本书 目录 文末送书 前言 当今 网络系统面临着越来越严峻的安全挑战 在众多的安全挑战中 一种有组织 有特定目标 长时间持续的新型网络攻击日益猖
  • 基于成本和服务质量考虑的不确定性下,电动汽车充电网络基础设施需求预测和迭代优化的分层框架研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据
  • 【CTF必看】从零开始的CTF学习路线(超详细),让你从小白进阶成大神!

    最近很多朋友在后台私信我 问应该怎么入门CTF 个人认为入门CTF之前大家应该先了解到底 什么是CTF 而你 学CTF的目的又到底是什么 其次便是最好具备相应的编程能力 若是完全不具备这些能力极有可能直接被劝退 毕竟比赛的时候动不动写个脚本
  • 5个步骤,教你瞬间明白线程和线程安全

    记得今年3月份刚来杭州面试的时候 有一家公司的技术总监问了我这样一个问题 你来说说有哪些线程安全的类 我心里一想 这我早都背好了 稀里哗啦说了一大堆 他又接着问 那你再来说说什么是线程安全 然后我就GG了 说真的 我们整天说线程安全 但是对
  • 38条Web测试经验分享

    1 页面链接检查 每一个链接是否都有对应的页面 并且页面之间切换正确 可以使用一些工具 如LinkBotPro File AIDCS HTML Link Validater Xenu等工具 LinkBotPro不支持中文 中文字符显示为乱码
  • 前端必备的 web 安全知识手记

    前言 安全这种东西就是不发生则已 一发生则惊人 作为前端 平时对这方面的知识没啥研究 最近了解了下 特此沉淀 文章内容包括以下几个典型的 web 安全知识点 XSS CSRF 点击劫持 SQL 注入和上传问题等 下文以小王代指攻击者 话不多
  • 【信道估计】【MIMO】【FBMC】未来移动通信的滤波器组多载波调制方案(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 远程控制软件安全吗?一文看懂ToDesk、RayLink、TeamViewer、Splashtop相关安全机制_raylink todesk

    目录 一 前言 二 远程控制中的安全威胁 三 国内外远控软件安全机制 ToDesk RayLink Teamviewer Splashtop 四 安全远控预防 一 前言 近期 远程控制话题再一次引起关注 据相关新闻报道 不少不法分子利用远程
  • 【网安神器篇】——WPScan漏洞扫描工具

    目录 一 Wordpress简介 二 WPScan介绍 三 安装 四 获取token 1 注册账号 2 拿到token 五 使用教程 1 常用选项 2 组合命令 1 模糊扫描 2 指定扫描用户 3 插件漏洞扫描 4 主题漏洞扫描 5 Tim
  • 网络安全(黑客)自学启蒙

    一 什么是网络安全 网络安全是一种综合性的概念 涵盖了保护计算机系统 网络基础设施和数据免受未经授权的访问 攻击 损害或盗窃的一系列措施和技术 经常听到的 红队 渗透测试 等就是研究攻击技术 而 蓝队 安全运营 安全运维 则研究防御技术 作
  • 网络安全基础知识面试题库

    1 基于路由器的攻击手段 1 1 源IP地址欺骗式攻击 入侵者从外部传输一个伪装成来自内部主机的数据包 数据包的IP是 内网的合法IP 对策 丢弃所有来自路由器外端口 却使用内部源地址的数据包 1 2 源路由攻击 入侵者让数据包循着一个不可
  • 一台java服务器可以跑多少个线程?

    一台java服务器可以跑多少个线程 一台java服务器能跑多少个线程 这个问题来自一次线上报警如下图 超过了我们的配置阈值 打出jstack文件 通过IBM Thread and Monitor Dump Analyzer for Java
  • 服务器VPS是什么意思?一文了解其含义与重要性

    在今天的数字时代 服务器扮演着至关重要的角色 它们是网站 应用程序和在线业务的基石 但是 你是否听说过VPS 本文将深入探讨什么是服务器VPS 以及为什么它在今天的互联网世界中如此重要 什么是服务器VPS 服务器的基本概念 在我们深入探讨V
  • 静态综合实验

    1 IP地址划分 192 168 1 0 27 用于主干拆分 192 168 1 32 27 用于用户拆分 192 168 1 64 27 用于用户拆分 192 168 1 96 27 用于用户拆分 192 168 1 128 27 用于用
  • 服务器中E5和I9的区别是什么,如何选择合适的配置

    随着科技的进步 服务器处理器的性能在不断攀升 其中 Intel的E5和I9系列处理器在业界具有广泛的影响力 而当我们在选择服务器的时候会有各种各样的配置让我们眼花缭乱不知道该怎么去选择 下面我跟大家分享一下E5跟I9有什么区别 方便我们在选

随机推荐

  • Android开发之EditText 详解(addTextChangedListener监听用户输入状态)

    为了实现像qq或者微信输入框的效果 当在EditText输入字符串时发送按钮显示 当输入框字符消除掉时按钮改变 所以这时候我就要用到addTextChangedListener 用它来监听用户输入状态 可以在监听中改变用户输入的内容或者提示
  • python读取和生成excel文件

    今天来看一下如何使用python处理excel文件 处理excel文件是在工作中经常用到的 python为我们考虑到了这一点 python中本身就自带csv模块 今天来看一下如何使用python处理excel文件 处理excel文件是在工作
  • 对象池(连接池):commons-pool2源码解析:GenericObjectPool的继承结构、构造方法

    概述 GenericObjectPool是apache commons pool 源码分析基于commons pool2 框架中的一个非常重要的类 解析GenericObjectPool就有必要先了解一下apache commons poo
  • 图文并茂开发AR小游戏全教程(二)

    需要识别卡 AR游戏 这个是不需要识别卡的 可放大缩小 旋转 感应重力偏移 可自行下载项目运行到真机上演示由于项目以及下文用到的素材较大 GItHub 无法上传 故传到百度云LLGameAR二 1 创建一个新场景 然后将新的场景保存成 Sc
  • 内网穿透——SSH远程连接树莓派

    前言 文章目录 前言 内网穿透实现公网SSH远程连接树莓派 1 在树莓派上安装 cpolar客户端 https www cpolar com 2 在树莓派浏览器中输入本地9200端口 3 在公共互联网的电脑的命令行界面输入命令 内网穿透实现
  • Python注释方式有哪些

    注释是对一段代码的解释和说明 可提高程序代码的可读性 让人们能够更加轻松地了解代码 尤其在大型项目开发和团队项目中 注释是必不可少的 任何编程语言都少不了注释 Python也不例外 以下是Python注释的具体用法 1 单行注释 Pytho
  • 抖音矩阵号系统搭建,企业同时管理1000+账号的基础逻辑

    短视频矩阵号系统开发功能涵盖 1 AI视频剪辑 2 创意灵感 3 多账号矩阵管理 4 视频排名优化 5 视频投放 6 企业号智能营销 6 AI视频拓客 7 企业员工管理等 开发思维导图如下 源码开发所需服务器配置 及环境 1 规格 最低4核
  • qt day1

    实现图形化登录界面 include myhomework h include
  • CUDA 动态链接库与静态链接库

    参考 CUDA C BEST PRACTICES GUIDE chapter 15 PREPARING FOR DEPLOYMENT 关于部署CUDA加速的程序时 往往对CUDA加速的程序编译为动态链接库或者静态链接库 这两者导致的区别是
  • python 8行代码搞定 AES加解密

    python 实现AES加解密相关的知识 可以参考以下文章 python实现AES加密解密 但该文章中 对于加密前数据的补全 及解密后去掉多余数据 由作者自己进行了封装 导致代码较为复杂 实际可以使用库中pad和unpad来解决该问题 而使
  • vue中实现高德地图上打点,并添加点击事件,

    文章目录 1 在地图上打点 并定义 click 事件 2 数据由websocket订阅 后台实时推送 3 实时失效 1 在地图上打点 并定义 click 事件 地图上打点 并定义click事件 param map map对象 param i
  • iviewui中表格控件中render的使用示例

    示例了如何在表格中显示按钮 如何将代码转化为文字 iviewui新版本中 如果内容转化输出时 如果不使用render函数 会显示不正常 老版本不存在这个问题
  • 阿里分布式事务框架-seata源码分析

    详细可参考 AT下流程图 TCC下流程图 基于该流程图可大致了解seata中TC TM RM这3个角色在seata框架中的作用 以及两种模式的优缺点
  • 数学建模常用模型(六):时间序列预测

    数学建模常用模型 六 时间序列预测 时间序列预测是数学建模中的一个重要领域 用于预测时间序列数据中未来的趋势和模式 时间序列预测可以帮助我们了解数据的演变规律 做出合理的决策和规划 这是我自己总结的一些代码和资料 本文中的代码以及参考书籍等
  • 移动Web应用的性能及其未来趋势

    在一篇深入的实质性文章中 某iOS开发公司的老板Drew Crawford表示他认为目前移动Web应用运行迟缓 而且并不指望能在不久的将来看到重大改善 并列出了以上观点的全部原因 该文章是此前某篇博客文章的后续之作 在那篇文章中 他指出 与
  • el-select 点击输入框不弹出选项的下拉框

    el select 点击输入框不弹出选项的下拉框 重点是绑定click事件 用它的event判断点击的是输入框还是下拉箭头 如果是输入框 就让它失去焦点 就不会弹出选项的下拉框
  • JSTL在JSP页面上的使用

    1 JSTL标准标签库 JSTL JSP标准标签库 JSTL 是一个JSP标签集合 它封装了JSP应用的通用核心功能 JSTL支持通用的 结构化的任务 比如迭代 条件判断 XML文档操作 国际化标签 SQL标签 除了这些 它还提供了一个框架
  • QNX的应用移植迁移到Linux

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额1元起步 多少随意 author 锋影 e mail 174176320 qq com 近年来许多嵌入式产品将是公司从自营到开放源代码平台为他们提供更多灵活性和成本
  • 基于微信小程序的manster云音乐小程序

    代码地址 https gitee com manster1231 master cloud music 介绍 基于网易云音乐真实接口开发的音乐小程序 软件架构 Nodejs作为后端 跨站请求伪造 CSRF 伪造请求头 调用官方 API 网易
  • 基于TCP的服务器端/客户端

    TCP服务器端默认函数调用顺序 socket 创建socket bind 分配socket地址 listen 等待连接请求状态 accept 允许连接 read write 数据交换 close 断开连接 等待连接请求状态 int list