当前位置: 首页 > wzjs >正文

企业网站建设的收获公众号怎么制作横屏长图文

企业网站建设的收获,公众号怎么制作横屏长图文,手机端网站开发视频教程,昌平网站开发文章目录 一、TCP编程基础TCP socket APIsocket二、EchoServer对于服务端对于客户端server.hppServer.ccClient.ccCommandExec.hpp 一、TCP编程基础 ​ TCP协议和UDP协议都属于网络通信协议,TCP协议是面向字节流的,UDP协议是面向数据报,这个…

文章目录

    • 一、TCP编程基础
    • TCP socket API
    • socket
    • 二、EchoServer
    • 对于服务端
    • 对于客户端
    • server.hpp
    • Server.cc
    • Client.cc
    • CommandExec.hpp

一、TCP编程基础

​ TCP协议和UDP协议都属于网络通信协议,TCP协议是面向字节流的,UDP协议是面向数据报,这个特点后面会详谈的。对于现在来说UDP和TCP的区别为:

UDP协议不需要连接,即报文一来就立刻进行转发

TCP协议则需要建立连接,只有双方准备好才能进行报文的转发

TCP socket API

socket

NAMEsocket - create an endpoint for communicationSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);
  • socket()打开一个网络通讯端口,如果成功的话,就像 open()一样返回一个文件描述符;
  • 应用程序可以像读写文件一样用 read/write 在网络上收发数据;
  • 如果 socket()调用出错则返回-1;
  • 对于 IPv4, family 参数指定为 AF_INET;
  • 对于 TCP 协议,type 参数指定为 SOCK_STREAM, 表示面向流的传输协议
  • protocol 参数的介绍从略,指定为 0 即可。

bind

NAMEbind - bind a name to a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  • 服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接; 服务器需要调用 bind 绑定一个固定的网络地址和端口号;
  • bind()成功返回 0,失败返回-1。
  • bind()的作用是将参数 sockfd 和 myaddr 绑定在一起, 使 sockfd 这个用于网络通讯的文件描述符监听 myaddr 所描述的地址和端口号;
  • 前面讲过,struct sockaddr *是一个通用指针类型,myaddr 参数实际上可以接受多种协议的 sockaddr 结构体,而它们的长度各不相同,所以需要第三个参数 addrlen指定结构体的长度;

listen

NAMElisten - listen for connections on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int listen(int sockfd, int backlog);
  • listen()声明 sockfd 处于监听状态, 并且最多允许有 backlog 个客户端处于连接等待状态, 如果接收到更多的连接请求就忽略, 这里设置不会太大(一般是 5);
  • listen()成功返回 0,失败返回-1

accept

NAMEaccept, accept4 - accept a connection on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#define _GNU_SOURCE             /* See feature_test_macros(7) */#include <sys/socket.h>int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);
  • 三次握手完成后, 服务器调用 accept()接受连接;
  • 如果服务器调用 accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来;
  • addr 是一个传出参数,accept()返回时传出客户端的地址和端口号;
  • 如果给 addr 参数传 NULL,表示不关心客户端的地址;
  • addrlen 参数是一个传入传出参数(value-result argument), 传入的是调用者提供的, 缓冲区 addr 的长度以避免缓冲区溢出问题, 传出的是客户端地址结构体的实际长度(有可能没有占满调用者提供的缓冲区);

connect

NAMEconnect - initiate a connection on a socketSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  • 客户端需要调用 connect()连接服务器;
  • connect 和 bind 的参数形式一致, 区别在于 bind 的参数是自己的地址, 而connect 的参数是对方的地址;
  • connect()成功返回 0,出错返回-1;

​ 对于accept和listen的理解:

listen可以理解为在景区餐馆旁边拉客的人,他的任务只是把你拉进餐馆,对于后续的服务并不做关心,在你进入餐馆后,继续进行拉客

accept可以理解为在你进入这个餐馆后进行招待的人,也就是由他来对你进行服务

二、EchoServer

​ 目标:

对于服务端

  1. 建立套接字

  2. 绑定套接字

  3. 监听等待

  4. 获取连接

  5. 提供服务

对于客户端

  1. 获取服务端IP和端口号
  2. 建立套接字
  3. 建立连接
  4. 发送消息

server.hpp

#pragma once#include <iostream>
#include <cstring>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <functional>#include "Log.hpp"
#include "Common.hpp"
#include "Inetaddr.hpp"
#include "ThreadPool.hpp"#define BACKLOG 8using namespace LogModule;
using namespace ThreadPoolModule;static const uint16_t gport = 8082;
using handler_t = std::function<std::string(std::string)>;class TcpServer
{using task_t = std::function<void()>;struct ThreadData{int sockfd;TcpServer *self;};
public:TcpServer(handler_t handler, int port): _handler(handler), _port(port), _isrunning(false){}void InitServer(){_listensockfd = socket(AF_INET, SOCK_STREAM, 0);if (_listensockfd < 0){LOG(LogLevel::FATAL) << "socket error";Die(SOCKET_ERR);}LOG(LogLevel::INFO) << "socket create success, sockfd is : " << _listensockfd;int opt = 1;setsockopt(_listensockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(gport);local.sin_addr.s_addr = INADDR_ANY;// 2. bindint n = ::bind(_listensockfd, CONV(&local), sizeof(local));if (n < 0){LOG(LogLevel::FATAL) << "bind error";Die(BIND_ERR);}LOG(LogLevel::INFO) << "bind success, sockfd is : " << _listensockfd;// 3. cs,tcp是面向连接的,就要求tcp随时随地等待被连接// tcp 需要将socket设置成为监听状态n = ::listen(_listensockfd, BACKLOG);if (n < 0){LOG(LogLevel::FATAL) << "listen error";Die(LISTEN_ERR);}LOG(LogLevel::INFO) << "listen success, sockfd is : " << _listensockfd;}void HandlerRequest(int sockfd) // TCP也是全双工通信的{LOG(LogLevel::INFO) << "HandlerRequest, sockfd is : " << sockfd;char inbuffer[4096];// 长任务while (true){// 约定:用户发过来的是一个完整的命令string// ssize_t n = ::read(sockfd, inbuffer, sizeof(inbuffer) - 1); // read读取是不完善ssize_t n = ::recv(sockfd, inbuffer, sizeof(inbuffer) - 1, 0); // read读取是不完善if (n > 0){LOG(LogLevel::INFO) << inbuffer;inbuffer[n] = 0;// std::string echo_str = "server echo# ";// echo_str += inbuffer;std::string cmd_result = _handler(inbuffer);::send(sockfd, cmd_result.c_str(), cmd_result.size(), 0); // 写入也是不完善}else if (n == 0){// read 如果读取返回值是0,表示client退出LOG(LogLevel::INFO) << "client quit: " << sockfd;break;}else{// 读取失败了break;}}::close(sockfd); // fd泄漏问题!}static void *ThreadEntry(void *args){pthread_detach(pthread_self());ThreadData *data = (ThreadData *)args;data->self->HandlerRequest(data->sockfd);return nullptr;}void Start(){_isrunning = true;while (_isrunning){// 不能直接读取数据// 1. 获取新连接struct sockaddr_in peer;socklen_t peerlen = sizeof(peer); // 这个地方一定要注意,要不然,会有问题!LOG(LogLevel::DEBUG) << "accept ing ...";// 我们要获取client的信息:数据(sockfd)+client socket信息(accept || recvfrom)int sockfd = ::accept(_listensockfd, CONV(&peer), &peerlen);if (sockfd < 0){LOG(LogLevel::WARNING) << "accept error: " << strerror(errno);continue;}// 获取连接成功了LOG(LogLevel::INFO) << "accept success, sockfd is : " << sockfd;InetAddr addr(peer);LOG(LogLevel::INFO) << "client info: " << addr.Addr();// version-0// HandlerRequest(sockfd);// version-1: 多进程版本// pid_t id = fork();// if (id == 0)// {//     // child//     // 问题1: 子进程继承父进程的文件描述符表。两张,父子各一张//     // 1. 关闭不需要的fd//     ::close(_listensockfd);//     if(fork() > 0) exit(0); //子进程退出//     // 孙子进程 -> 孤儿进程 -> 1//     HandlerRequest(sockfd);//     exit(0);// }// ::close(sockfd);// // 不会阻塞// int rid = ::waitpid(id, nullptr, 0);// if(rid < 0)// {//     LOG(LogLevel::WARNING) << "waitpid error";// }// version-2: 多线程版本// 主线程和新线程是如何看待:文件描述符表,共享一张文件描述符表!!// pthread_t tid;// ThreadData *data = new ThreadData;// data->sockfd = sockfd;// data->self = this;// pthread_create(&tid, nullptr, ThreadEntry, data);// version-3:线程池版本 比较适合处理短任务,或者是用户量少的情况// task_t f = std::bind(&TcpServer::HandlerRequest, this, sockfd); // 构建任务//ThreadPool<task_t>::getInstance()->Equeue([this, sockfd]()//                                          { this->HandlerRequest(sockfd); });}}void Stop(){_isrunning = false;}~TcpServer(){}private:uint16_t _port;int _listensockfd;bool _isrunning;handler_t _handler;
};

Server.cc

#include "TcpServer.hpp"
#include "CommandExec.hpp"
#include <memory>using namespace LogModule;int main()
{ENABLE_CONSOLE_LOG();Command cmd;std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&cmd](std::string cmdstr){return cmd.Execute(cmdstr);});tsvr->InitServer();tsvr->Start();return 0;
}

Client.cc

#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>// ./client_tcp server_ip server_port
int main(int argc, char *argv[])
{if (argc != 3){std::cout << "Usage:./client_tcp server_ip server_port" << std::endl;return 1;}std::string server_ip = argv[1]; // "192.168.1.1"int server_port = std::stoi(argv[2]);int sockfd = ::socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){std::cout << "create socket failed" << std::endl;return 2;}struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(server_port);server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());// client 不需要显示的进行bind, tcp是面向连接的, connect 底层会自动进行bindint n = ::connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));if(n < 0){std::cout << "connect failed" << std::endl;return 3;}// echo clientstd::string message;while(true){char inbuffer[1024];std::cout << "input message: ";std::getline(std::cin, message);n = ::write(sockfd, message.c_str(), message.size());if(n > 0){int m = ::read(sockfd, inbuffer, sizeof(inbuffer));if(m > 0){inbuffer[m] = 0;std::cout << inbuffer << std::endl;}elsebreak;}else break;}::close(sockfd);return 0;
}

CommandExec.hpp

#pragma once#include <iostream>
#include <string>
#include <cstdio>
#include <set>const int line_size = 1024;class Command
{
public:Command(){_white_list.insert("ls");_white_list.insert("pwd");_white_list.insert("ls -l");_white_list.insert("ll");_white_list.insert("touch");_white_list.insert("who");_white_list.insert("whoami");}bool SafeCheck(const std::string &cmdstr){auto iter = _white_list.find(cmdstr);return iter == _white_list.end() ? false : true;}// 给你一个命令字符串"ls -l", 让你执行,执行完,把结果返回std::string Execute(std::string cmdstr){// 1. pipe// 2. fork + dup2(pipe[1], 1) + exec* , 执行结果给父进程,pipe[0]// 3. return// FILE *popen(const char *command, const char *type);// int pclose(FILE * stream);if (!SafeCheck(cmdstr)){return std::string(cmdstr + " 不支持");}FILE *fp = ::popen(cmdstr.c_str(), "r");if (nullptr == fp){return std::string("Failed");}char buffer[line_size];std::string result;while (true){char *ret = ::fgets(buffer, sizeof(buffer), fp);if (!ret)break;result += ret;}pclose(fp);return result.empty() ? std::string("Done") : result;}private:std::set<std::string> _white_list;
};

文章转载自:

http://adiHCXTH.gpnfg.cn
http://30V6uUS2.gpnfg.cn
http://TOvyfVFe.gpnfg.cn
http://dwxpW6cG.gpnfg.cn
http://0qpZmnvh.gpnfg.cn
http://qFHI2gQX.gpnfg.cn
http://zQnyzY00.gpnfg.cn
http://Sy1vlEkT.gpnfg.cn
http://NV2UKiES.gpnfg.cn
http://JQhyp2zu.gpnfg.cn
http://WrSy1LMt.gpnfg.cn
http://ElwtYFhV.gpnfg.cn
http://aDP4dZL8.gpnfg.cn
http://mvdJGGpQ.gpnfg.cn
http://CL33rxLo.gpnfg.cn
http://T5OXDXOU.gpnfg.cn
http://N1DKm4Ay.gpnfg.cn
http://7RZlGMJo.gpnfg.cn
http://Y6WJXzYY.gpnfg.cn
http://tAj0CylB.gpnfg.cn
http://Qv3etGWH.gpnfg.cn
http://pO9DFr5j.gpnfg.cn
http://o282EZhn.gpnfg.cn
http://YPXKSrzj.gpnfg.cn
http://ADBg5I4Q.gpnfg.cn
http://snjV7zU7.gpnfg.cn
http://4aBD2F2P.gpnfg.cn
http://0sqByKjL.gpnfg.cn
http://YLtT2Yhn.gpnfg.cn
http://iF3hb6Zt.gpnfg.cn
http://www.dtcms.com/wzjs/630489.html

相关文章:

  • 建设银行官方网站买五粮液酒wordpress 固定连接中文转换插件
  • 怎样做网站的优化工作网页制作的目的
  • 苏州工业园区建设局网站朔州seo
  • 网站也会过期吗沧州网站建设公司排名
  • 达州市网站建设金华专业的网站建设
  • 烟台做网站多钱网站建设费用要多少
  • 如何做一个网站的功能吗网站后缀有哪些
  • 公司网站建设要求书奇艺广州网站建设熊掌号
  • 怎么知道网站谁建的app推广方案怎么写
  • 免费自助开通网站莱芜最新
  • 手机版传奇网站封丘有做网站的吗
  • 建设通网站上的业绩能否有用tooopen素材公社
  • 网站建设得步骤网站建设合同 完整版
  • 连云港网站 建设玉林seo
  • 检察网站建设wordpress安装微信登录插件
  • 手机网站大全免费下载上海做网站优化价格
  • 都有哪些js素材网站商贸公司起名大全最新
  • 百度不做网站外链是什么枣庄做网站
  • 网络规划设计师教程电子版2023宁波企业网站优化报价
  • 做影视网站 片源从哪里来做导购网站如何获利
  • 做网站怎么在图片上加文字海外网站建站
  • 齐河建设局网站网站建设服务预算
  • 网站备案账号是什么宣传推广
  • 个人网站可以直接做微信登陆吗合肥市住建局官方网
  • 代做毕设网站推荐二级目录 wordpress 伪静态
  • 犀牛云网站怎么建设外贸网络营销该如何做
  • 优质的杭州网站优化曲靖网站建设dodoco
  • 免费下载建筑图纸的网站网站建设要备案吗
  • 页面设计好看的网站毕业设计怎么做网站
  • 做贸易选哪家网站成都专业建网站公司