TCP服务器—实现数据通信

目录

前言

1.接口介绍

2.编写服务器

3.编写客户端

4.编译链接

5.测试

6.总结


前言

        今天我们要介绍的是使用TCP协议实现数据通信,相比于之前写的UDP服务器实现数据信,在主体逻辑上并没有差别。客户端向服务器发送信息,服务器接受信息并回显,因为UDP是面向数据报,而TCP是面向连接的,所以在实现的时候接口上会有一些差别,下面,我们具体来看看UDP和TCP在编码的实现上有什么不同。

1.接口介绍

因为TCP是面向连接的,所以服务器创建完套接字,然后绑定成功后,将套接字设置为监听套接字

服务器启动之后,首先需要根据监听套接字建立连接,建立连接成功后返回一个新的文件描述符,后续的通信都是按照这个新的文件描述符按照读写文件的形式进行读写数据。

对于客户端来说创建完套接字之后,客户端启动之后首先需要建立连接

listen():设置sock为监听状态

 #include <sys/types.h>       #include <sys/socket.h>int listen(int sockfd, int backlog);

sockfd:创建套接字的返回值

backlog:底层全连接队列的长度

accept():服务端建立连接

#include <sys/types.h>         
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

sockfd:监听套接字

struct sockaddr* addr:输出型参数,可以获取服务端的IP地址和port端口号

socklen_t* addrlen:结构体的大小

返回值:返回一个新打开的文件描述符

connect():客户端建立连接

#include <sys/types.h>        
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

sockfd:创建套接字返回值

struct sockaddr* addr:输出型参数,用来填写需要访问的服务端的IP地址和port端口号

socklen_t addrlen:结构体的大小

2.编写服务器

tcpServer.hpp

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "log.hpp"
namespace server
{using namespace std;enum{USAGE_ERR = 1,SOCKET_ERR,BIND_ERR,LISTEN_ERR};static const uint16_t gport = 8080;static const int gback = 5;class TcpServer{public:TcpServer(const uint16_t &port = gport): _port(gport), _sock(-1){}void InitServer(){_sock = socket(AF_INET, SOCK_STREAM, 0);if (_sock < 0){logMessage(FATAL, "create socket error");exit(SOCKET_ERR);}logMessage(NORMAL, "create socket success");// 绑定:struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY;if (bind(_sock, (struct sockaddr *)&local, sizeof(local)) < 0){logMessage(FATAL, "bind socket error");exit(BIND_ERR);}logMessage(NORMAL, "bind socket success");// 设置sock为监听状态:if (listen(_sock, gback) < 0){logMessage(FATAL, "listen socket error");exit(LISTEN_ERR);}logMessage(NORMAL, "listen socket success");}void start(){for (;;){// 建立连接:struct sockaddr_in peer;socklen_t len = sizeof(peer);int sock = accept(_sock, (struct sockaddr *)&peer, &len); if (sock < 0){logMessage(ERROR, "accept error, next");continue;}logMessage(NORMAL, "accept a new link success");std::cout << "sock: " << sock << std::endl;//未来通信全部用sock,面向字节流的,后续全部都是文件操作:serviceIO(sock);close(sock);}}void serviceIO(int sock){char buffer[1024];while(true){ssize_t n = read(sock,buffer,sizeof(buffer)-1);if(n > 0){buffer[n] = 0;cout << "recvice message: " << buffer << endl;string outbuffer = buffer;outbuffer += "[server echo]";write(sock,outbuffer.c_str(),outbuffer.size());}else if(n == 0){// 代表client退出logMessage(NORMAL, "client quit, me too!");break;}}}~TcpServer(){}private:int _sock;uint16_t _port;};
}

tcpServer.cc:启动服务器

#include"tcpServer.hpp"
#include<memory>
using namespace server;
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc,char* argv[])
{if(argc != 2){Usage(argv[0]);exit(USAGE_ERR);}uint16_t port = atoi(argv[1]);unique_ptr<TcpServer> tcs(new TcpServer(port));tcs->InitServer();tcs->start();return 0;
}

3.编写客户端

tcpClient.hpp

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>namespace client
{using namespace std;class TcpClient{public:TcpClient(const string& serverip,const uint16_t port):_serverip(serverip),_port(port),_sock(-1){}void InitClient(){_sock = socket(AF_INET,SOCK_STREAM,0);if(_sock < 0){cerr << "create sock fail" << endl;exit(-1);}}void start(){//建立连接:struct sockaddr_in server;server.sin_family = AF_INET;server.sin_port = htons(_port);server.sin_addr.s_addr = inet_addr(_serverip.c_str());if(connect(_sock,(struct sockaddr*)&server,sizeof(server)) != 0){cerr << "connect fail" << endl;}else{string message;while(true){cout << "Please Enter: ";getline(cin,message);write(_sock,message.c_str(),message.size());char buffer[1024];int n = read(_sock,buffer,sizeof(buffer)-1);if(n > 0){buffer[n] = 0;cout << "Server回复: " << buffer << endl;}else{break;}}}}~TcpClient(){if(_sock >= 0)close(_sock);}private:string _serverip;uint16_t _port;int _sock;};
} // namespace client

tcpClient.cc:启动客户端

#include"tcpClient.hpp"
#include<memory>
using namespace client;
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " serverip serverport\n\n";
}
int main(int argc,char* argv[])
{if(argc != 3){Usage(argv[0]);exit(-1);}uint16_t port = atoi(argv[2]);string ip = argv[1];unique_ptr<TcpClient> tcc(new TcpClient(ip,port));tcc->InitClient();tcc->start();return 0;
}

4.编译链接

makefile:

.PHONY:all
all:tcpServer tcpClient
tcpServer:tcpServer.ccg++ -o $@ $^ -std=c++11
tcpClient:tcpClient.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm tcpServer tcpClient

5.测试

 如图所示,服务端和客户端可以完成正常的数据通信了。

6.总结

        TCP协议和UDP协议在数据通信的实现中,除了一些接口使用的不同之外,其实并没有太大的不同,在之前说的UDP是面向数据报的而TCP是面向字节流的,这些特性又是如何体现的呢?关于这个问题,博主将在后面的文章中会为大家继续进行介绍。不要错过哦!

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

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

相关文章

JavaEE初阶:多线程 - Thread 类的基本用法

上次我们了解了多线程的五种创建方法&#xff0c;今天来学习Thread的基本用法。 目录 run和start Thread常见的构造方法 Thread的几个常见属性 后台线程 是否存活 线程终止 1.使用标志位 2.使用Thread自带的标志 等待线程 run和start 首先需要理解Thread的run和star…

JavaWeb-Listener监听器

目录 监听器Listener 1.功能 2.监听器分类 3.监听器的配置 4.ServletContext监听 5.HttpSession监听 6.ServletRequest监听 监听器Listener 1.功能 用于监听域对象ServletContext、HttpSession和ServletRequest的创建&#xff0c;与销毁事件监听一个对象的事件&#x…

Python源码05:使用Pyecharts画词云图图

**Pyecharts是一个用于生成 Echarts 图表的 Python 库。Echarts 是一个基于 JavaScript 的数据可视化库&#xff0c;提供了丰富的图表类型和交互功能。**通过 Pyecharts&#xff0c;你可以使用 Python 代码生成各种类型的 Echarts 图表&#xff0c;例如折线图、柱状图、饼图、散…

Glide 的超时控制相关处理

作者&#xff1a;newki 前言 Glide 相信大家都不陌生&#xff0c;各种源码分析&#xff0c;使用介绍大家应该都是烂熟于心。但是设置 Glide 的超时问题大家遇到过没有。 我遇到了&#xff0c;并且掉坑里了&#xff0c;情况是这样的。 调用接口从网络拉取用户头像&#xff0c…

3.微服务概述

1.大型网络架构变迁 SOA与微服务最大的差别就是服务拆分的细度&#xff0c;目前大多数微服务实际上是SOA架构&#xff0c;真正的微服务应该是一个接口对应一个服务器&#xff0c;开发速度快、成本高&#xff1b; 微服务SOA能拆分的就拆分是整体的&#xff0c;服务能放一起的都…

【计算机网络】13、ARP 包:广播自己的 mac 地址和 ip

机器启动时&#xff0c;会向外广播自己的 mac 地址和 ip 地址&#xff0c;这个即称为 arp 协议。范围是未经过路由器的部分&#xff0c;如下图的蓝色部分&#xff0c;范围内的设备都会在本地记录 mac 和 ip 的绑定信息&#xff0c;若有重复则覆盖更新&#xff08;例如先收到 ma…

【Spring】深入理解 Spring 事务及其传播机制

文章目录 一、Spring 事务是什么二、Spring 中事务的实现方法2.1 Spring 编程式事务&#xff08;手动&#xff09;2.1.1 编程式事务的使用演示2.1.2 编程式事务存在的问题 2.2 Spring 声明式事务&#xff08;自动&#xff09;2.2.1 Transactional 作用范围2.2.2 Transactional …

腾讯云GPU服务器GN7实例NVIDIA T4 GPU卡

腾讯云GPU服务器GN7实例搭载1颗 NVIDIA T4 GPU&#xff0c;8核32G配置&#xff0c;系统盘为100G 高性能云硬盘&#xff0c;自带5M公网带宽&#xff0c;系统镜像可选Linux和Windows&#xff0c;地域可选广州/上海/北京/新加坡/南京/重庆/成都/首尔/中国香港/德国/东京/曼谷/硅谷…

安卓纯代码布局开发游戏二:Android Studio开发环境搭建

1.Android Studio下载&#xff1a; Download Android Studio & App Tools - Android Developers 2.安装 安装过程非常简单&#xff0c;找到下载包&#xff0c;一直点Next即可。 3.下载Android SDK 第一次进入Android Studio默认会先下载Android SDK,笔者下载的Android SDK存…

零售行业供应链管理核心KPI指标(三)

完美订单满足率和退货率 完美订单满足率有三个方面的因素影响&#xff1a;订单按时、足量、无损交货。通常情况下零售企业追求线上订单履行周期慢慢达到行业平均水平&#xff0c;就是交付的速度变快了&#xff0c;这个肯定是一件好事情&#xff0c;趋势越来越好。 同时&#…

欧拉公式

文章目录 欧拉公式e欧拉恒等式欧拉公式欧拉公式 推导2步骤1: 使用泰勒级数展开步骤2: 将 i x i x ix 代入 e x e^x ex 复平面上推导欧拉公式步骤1&#xff1a;复平面上的复数表示步骤2&#xff1a;定义复数的指数形式步骤3&#xff1a;求导步骤4&#xff1a;连接两种形式步骤…

星际争霸之小霸王之小蜜蜂(一)

目录 前言 一、安装pygame库 1、pygame库简介 2、在windows系统安装pygame库 二 、搭建游戏框架 1、创建游戏窗口 2、改变窗口颜色 总结 前言 大家应该都看过或者都听说过python神书“大蟒蛇”&#xff0c;上面有一个案例是《外星人入侵》&#xff0c;游戏介绍让我想起了上…

炫酷UI前端效果的CSS生成工具

提升设计人员和前端开发人员的工作 推荐炫酷UI前端效果的CSS生成工具1.Neumorphism2.带有渐变的图标3.Interactions4.大型数据库5.动画6.Mask7.动画按钮8. 自定义形状分隔线9.背景图案10. SVG波浪推荐炫酷UI前端效果的CSS生成工具 1.Neumorphism 地址:https://neumorphism.i…

【Nginx17】Nginx学习:目录索引、字符集与浏览器判断模块

Nginx学习&#xff1a;目录索引、字符集与浏览器判断模块 今天要学习的内容有几个还是大家比较常见的&#xff0c;所以学习起来也不会特别费劲。对于目录的默认页设置大家都不会陌生&#xff0c;字符集的设置也比较常见&#xff0c;而浏览器的判断这一块&#xff0c;可能有同学…

深入源码分析kubernetes informer机制(二)Reflector

[阅读指南] 这是该系列第二篇 基于kubernetes 1.27 stage版本 为了方便阅读&#xff0c;后续所有代码均省略了错误处理及与关注逻辑无关的部分。 文章目录 Reflector是什么整体结构工作流程list拉取数据缓存resync操作watch监听操作 总结 Reflector是什么 reflector在informer…

RocketMQ双主双从同步集群部署

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

学习笔记十九:Pod常见的状态和重启策略

Pod常见的状态和重启策略 常见的pod状态第一阶段&#xff1a;第二阶段&#xff1a;扩展&#xff1a; pod重启策略测试Always重启策略正常停止容器内的tomcat服务非正常停止容器里的tomcat服务 测试never重启策略正常停止容器里的tomcat服务非正常停止容器里的tomcat服务 测试On…

Mac安装opencv后无法导入cv2的解决方法

前提条件&#xff1a;以下两个插件安装成功 pip install opencv-python pip install --user opencv-contrib-python 注&#xff1a;直接用pip install opencv-contrib-python如果报错&#xff0c;就加上“–user" 第一步&#xff1a; 设置–添加python解释器 第二步&am…

go语言恶意代码检测系统--对接前端可视化与算法检测部分

Malware Detect System 1 产品介绍 恶意代码检测系统。 2 产品描述 2.1 产品功能 功能点详细描述注册账号未注册用户注册成为产品用户&#xff0c;从而具备享有产品各项服务的资格登录账号用户登录产品&#xff0c;获得产品提供的各项服务上传恶意样本用户可以将上传自己的…

uniapp微信小程序消息订阅快速上手

一、微信公众平台小程序开通消息订阅并设置模板 这边的模板id和详细内容后续前后端需要使用 二、uniapp前端 需要是一个button触发 js&#xff1a; wx.getSetting({success(res){console.log(res)if(res.authSetting[scope.subscribeMessage]){// 业务逻辑}else{uni.request…