socket编程实现TCP通信

socket编程实现TCP通信

tcp_client.cc

#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>
#include <cerrno>
#include "log.hpp"
#define SIZE 1024
uint16_t serverport;
std::string serverip;
void *tcpSend(void *args)
{int sock = *(int *)args;std::string message;while (true){std::cerr << "请输入你的信息# ";std::getline(std::cin, message);send(sock, message.c_str(), message.size(), 0);}
}void *tcpRecv(void *args)
{int sock = *(int *)args;char buff[1024];while (true){ssize_t s = recv(sock, buff, sizeof(buff) - 1, 0);if (s > 0){buff[s] = '\0';printf("%s\n", buff);fflush(stdout);}}
}
int main(int argc, char *argv[])
{if (argc != 3){std::cout << "Usage: " << argv[0] << " ip port" << std::endl;exit(1);}int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){std::cerr << "FATAL " << errno << ":" << strerror(errno);exit(2);}serverport = atoi(argv[2]);serverip = argv[1];struct sockaddr_in server;memset(&server, 0, sizeof server);server.sin_family = AF_INET;server.sin_port = htons(serverport);server.sin_addr.s_addr = inet_addr(serverip.c_str());if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1) {printf("连接失败 [%d:%s]\n",errno,strerror(errno));close(sock);exit(1);}LogMessage(NORMAL,"connect success");pthread_t t1, t2;pthread_create(&t1, nullptr, tcpSend, (void *)&sock);pthread_create(&t2, nullptr, tcpRecv, (void *)&sock);pthread_join(t1, nullptr);pthread_join(t2, nullptr);close(sock);return 0;
}

tcp_server.cc

#include "tcp_server.hpp"
int main(int argc,char* argv[])
{if(argc != 2){std::cout<<"Usage: "<<argv[0]<<" port"<<std::endl;exit(1);}uint16_t port = atoi(argv[1]);TcpServer* svr = new TcpServer(port);svr->initServer();svr->start();delete svr;return 0;
}

tcp_server.hpp

#ifndef UDP_SERVER_HPP
#define UDP_SERVER_HPP#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unordered_map>
#include <unistd.h>
#include <signal.h>
#include <wait.h>
#include "log.hpp"#define SIZE 1024static void service(int sock, std::string &client_ip, uint16_t &client_port)
{char buff[1024];while (true){ssize_t s = read(sock, buff, sizeof(buff) - 1);if (s > 0){buff[s] = '\0';printf("[%s:%d]# %s\n", client_ip.c_str(), client_port, buff);}else if (s == 0){LogMessage(NORMAL, "[%s:%d] shutdown, me too!", client_ip.c_str(), client_port);break;}else{LogMessage(ERROR, "read socket error, %d:%s", errno, strerror(errno));break;}write(sock, buff, strlen(buff));}
}
struct ThreadData
{int _sock;std::string _ip;uint16_t _port;
};
class TcpServer
{
private:const int gbacklog = 20;public:static void* threadRoutine(void* args){pthread_detach(pthread_self());ThreadData* td = (ThreadData*)args;service(td->_sock, td->_ip, td->_port);delete td;return nullptr;}TcpServer(uint16_t port, std::string ip = "0.0.0.0"): _port(port), _listensock(-1),_ip(ip){}void initServer(){// 创建套接字_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){LogMessage(FATAL, "socket error, %d:%s", errno, strerror(errno));exit(2);}// 绑定struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = inet_addr(_ip.c_str());if (bind(_listensock, (struct sockaddr *)&local, sizeof(local)) < 0){LogMessage(FATAL, "bind error, %d:%s", errno, strerror(errno));exit(3);}// 建立连接(监听)if (listen(_listensock, gbacklog) < 0){LogMessage(FATAL, "listen error, %d:%s", errno, strerror(errno));exit(4);}LogMessage(NORMAL, "init TCP server success, listensock: %d", _listensock);}void start(){signal(SIGCHLD,SIG_IGN);//不理会子进程 v2.1while (true){// 获取连接struct sockaddr_in src;socklen_t len = sizeof(src);int servicesock = accept(_listensock, (struct sockaddr *)&src, &len);std::cout<<servicesock<<std::endl;if (servicesock < 0){LogMessage(ERROR, "accept error, %d:%s", errno, strerror(errno));continue;}uint16_t client_port = ntohs(src.sin_port);std::string client_ip = inet_ntoa(src.sin_addr);LogMessage(NORMAL, "link success, [%s:%d]", client_ip.c_str(), client_port);// 获取连接成功,开始通信服务// v1 单进程循环//service(servicesock, client_ip, client_port);//v2.0 多进程// pid_t id = fork();// if(id == 0)// {//     close(_listensock);//     service(servicesock, client_ip, client_port);//     exit(0);// }// close(servicesock);//v2.1 多进程// pid_t id = fork();// if(id == 0)// {//     close(_listensock);//     if(fork() > 0) exit(0);//     service(servicesock, client_ip, client_port);// }// waitpid(id,nullptr,0);// close(servicesock);//v3 多线程ThreadData* td = new ThreadData;td->_sock = servicesock;td->_ip = client_ip;td->_port = client_port;pthread_t tid;pthread_create(&tid,nullptr,threadRoutine,(void*)td);close(servicesock);}}private:uint16_t _port;std::string _ip;int _listensock;
};
#endif

log.hpp

#pragma once
#include<iostream>
#include<cstdio>
#include<cstdarg>
#include<ctime>
#include<string>#define DEBUG   0
#define NORMAL  1
#define WARNING 2
#define ERROR   3
#define FATAL   4
const char* gLevelMap[]={"DEBUG","NORMAL","WARNING","ERROR","FATAL"};void LogMessage(int level,const char* format,...)
{char stdBuffer[1024] = {'\0'};time_t timestamp = time(nullptr);snprintf(stdBuffer,sizeof stdBuffer,"[%s] [%ld]",gLevelMap[level],timestamp);char logBuffer[1024] = {'\0'};;va_list args;va_start(args,format);vsnprintf(logBuffer,sizeof logBuffer,format,args);va_end(args);printf("%s%s\n",stdBuffer,logBuffer);
}

makefile

.PHONY:add
all:tcp_client tcp_server
tcp_client:tcp_client.ccg++ -o $@ $^ -std=c++11 -l pthread
tcp_server:tcp_server.ccg++ -o $@ $^ -std=c++11 -l pthread
.PHONY:clean
clean:rm -f tcp_client tcp_server

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

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

相关文章

CV 面试指南—深度学习知识点总结(4)

本期专栏文章: CV 面试指南—深度学习知识点总结(1)CV 面试指南—深度学习知识点总结(2)CV 面试指南—深度学习知识点总结(3)CV 面试指南—深度学习知识点总结(4)CV 面试指南—深度学习知识点总结(5)

Qt——选中所有的RadioButton

在Qt中&#xff0c;如果想选中所有的RadioButton&#xff1a; 1. 你需要找到包含所有RadioButton的父控件&#xff0c;比如一个QGroupBox或者一个QWidget。 2. 使用父控件的findChildren函数来查找所有的RadioButton控件。这个函数会返回一个QObjectList&#xff0c;其中包含了…

windows部署pgsql

1、下载&#xff1a;Download PostgreSQL Binaries 2、创建data目录作为数据目录 3、初始化 bin目录执行命令&#xff1a; .\initdb.exe -D E:\pgsql\data -E UTF-8 --localechs -U postgres -W 输入密码直到完成 4、启动数据库 .\pg_ctl.exe -D E:\pgsql\data -l logfil…

C# Socket发送、接收结构体数组

C# Socket发送、接收结构体-CSDN博客 C# Socket发送、接收结构体数组按以下步骤操作&#xff1a; 一、Socket发送结构体数组 定义结构体数组 首先&#xff0c;根据给定的结构体定义&#xff0c;创建一个结构体数组实例。 [StructLayout(LayoutKind.Sequential, Pack 0)] p…

【基础】在GCC中编译和链接不是一个命令

在 GCC&#xff08;GNU Compiler Collection&#xff09;中&#xff0c;编译和链接不是一个命令。编译是将源代码转换为目标代码的过程。它主要进行语法检查、词法分析、生成中间代码等操作。链接是将多个目标文件和库文件组合成一个可执行文件的过程。在 GCC 中&#xff0c;通…

实战1-批量爬取百度图片(上)

任务需求&#xff1a;输入关键字下载100个图片保存到本地&#xff0c;每个关键字单独存放一个文件夹&#xff08;GUI版&#xff09; 任务描述&#xff1a;当输入关键字时会爬取100个与关键词有关的图片到本地每个关键词单独保存到一个文件夹中&#xff0c;比如说我输入黑客下载…

SpringBoot(二)【整合第三方技术】

1、SpringBoot 整合第三方框架 1.1、整合 JUnit 我们先回顾一下在学习 SpringMVC 的时候&#xff0c;我们当时整合 Spring 和 JUnit 是这么整合的&#xff1a; 注意&#xff1a;如果测试类在 SpringBoot 启动类的包或者子包中&#xff0c;可以省略启动类的设置&#xff0c;也…

【面试经典 150 | 二叉树层序遍历】二叉树的层平均值

文章目录 写在前面Tag题目来源题目解读方法一&#xff1a;层序遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

4.18日paddleocr报错记录

No Images in train dataset, please ensure 1. The images num in the train label_file_list should be larger than or equal with batch size. 2. The annotation file and path in the configuration file are provided normally. 发现是ch_PP-OCRv3_rec.yml的loader的问…

设计模式——策略模式20

策略模式是一种行为设计模式&#xff0c; 它能让你定义多种算法或行为方式&#xff0c; 并将具体实现放入独立的类中&#xff0c; 以使算法的对象能够相互替换。使用场景例如活动中多种打折策略。 策略抽象 /*** author ggbond* date 2024年04月18日 08:02*/ public interfa…

Hive进阶(1)----HDFS写入数据流程(赋图助君理解)

HDFS写入数据流程 1.理论流程描述 HDFS&#xff08;Hadoop分布式文件系统&#xff09;的数据写入流程是一个复杂但高效的过程&#xff0c;可以分为以下8个步骤&#xff1a; 1、client(客户端)发起文件上传请求&#xff1b; 2、通过发送RPC请求与NameNode建立通讯。NameNode…

【MySQL篇】mysqlpump和mysqldump参数区别总汇(第三篇,总共四篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…

递归 python

↵一、简单理解 解决问题的一种方法&#xff0c;它将问题不断的分成更小的子问题&#xff0c;直到子问题可以用普通的方法解决。通常情况下&#xff0c;递归会使用一个不停调用自己的函数。 【注】&#xff1a;每一次递归调用都是在解决一个更小的问题&#xff0c;如此进行下…

python安装pytorch@FreeBSD(失败)

pip 安装 在FreeBSD系统下pip安装pytorch&#xff0c;报错 Building wheels for collected packages: pytorchBuilding wheel for pytorch (setup.py) ... errorerror: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully.│ exit code: 1╰…

内核编译-02

1配置【u-boot】 查看版本信息 对arm文件进行编译的专用工具 打开脚本文件 配置脚本文件 编译【.c】文件 创建目录&#xff0c;解压文件夹&#xff1a; 编译【smdk2440_config】&#xff0c;并产生【u-boot.bin】&#xff1a; 2配置开发板对应的配置文件 这里采用菜单…

基于深度学习的光场超分辨率算法综述

摘要&#xff1a;光场图像分辨率低的原因之一是光场空间分辨率和角度分辨率之间存在相互制约。光场超分辨率技术旨在从低分辨率光场图像中重建出高分辨率光场图像。基于深度学习的光场超分辨率方法通过学习高、低分辨率光场图像之间的映射关系来提升图像的质量&#xff0c;突破…

亚马逊Bedrock凭借Anthropic的开创性Claude 3系列扩展了AI产品组合

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

云服务器部署Springboot项目

前端项目打包 修改ip地址 在控制台输入npm run build:prod 会产生dist文件 将dist文件中的内容移动至/usr/local/nginx/html目录下 后端项目打包 修改ip地址 执行clean操作 执行install操作 将生成的target文件中的jar包移动至/usr/local/src目录下 启动 注意⚠️&#xff…

动态规划-不同路径

LCR 098. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 对于动态规划类型的题目&#xff0c;可以从以下角度去思考问题 1. 状态表示 机器人在每一个网格节点的状态 dp[i][j] &#xff0c;可以理解从 起始点 为走到 [i,j] &#xff0c;一共有多少种方式&#xff1b; 2. …

vscode按ctrl+鼠标左键没反应

vscode按ctrl鼠标左键没反应 问题问题解决 问题 新买的阿里云服务器,在连接vscode后,按ctrl鼠标左键没反应,怎么办? 问题解决 你没有在vscode上安装c的相关插件,安装之后才可以实现按ctrl鼠标左键跳转到函数的定义