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

长沙企业网站深圳seo优化

长沙企业网站,深圳seo优化,网站设计 加英文费用,wordpress做导航页面模板目录 前言 TCP通信流程 TCP通信的代码实现 tcp_server.hpp编写 tcp_server.cc服务端的编写 tcp_client.cc客户端的编写 整体代码 前言 上一章我们主要讲解了UDP之间的通信#xff0c;本章我们将来讲述如何使用TCP来进行网络间通信#xff0c;主要是使用socket API进…目录 前言  TCP通信流程  TCP通信的代码实现 tcp_server.hpp编写 tcp_server.cc服务端的编写 tcp_client.cc客户端的编写 整体代码 前言  上一章我们主要讲解了UDP之间的通信本章我们将来讲述如何使用TCP来进行网络间通信主要是使用socket API进行代码的实现。 我们一共讲了5个socket API接口分别为socketbindlistenacceptconnect.但我们在讲解UDP通信时只使用了socket和bind这两个接口就完成了。而TCP通信会使用后面这三个接口我们将分别讲解. TCP通信流程  同样地TCP通信分为服务器端和客户端它们的流程分别如下 服务端通信流程 创建套接字使用socket函数创建一个套接字指定协议族为AF_INETIPv4或AF_INET6IPv6指定类型为SOCK_STREAMTCP。 绑定套接字使用bind函数将套接字与服务器的IP地址和端口号绑定在一起。这样服务器将使用指定的IP地址和端口号进行监听。 监听连接请求使用listen函数开始监听连接请求。指定参数backlog表示允许在队列中等待的最大连接数。 接受连接请求使用accept函数接受客户端的连接请求。该函数会阻塞程序直到有客户端连接时才返回一个新的套接字用于与客户端进行通信。(新的套接字和旧套接字区别新套接字负责服务建立的连接包括通信等旧套接字则一直负责监听连接.) 通信使用新的套接字进行通信。可以使用read和write函数进行数据的接收和发送。 关闭连接当通信结束后使用close函数关闭套接字释放资源。 客户端通信流程 创建套接字使用socket函数创建一个套接字指定协议族为AF_INETIPv4或AF_INET6IPv6指定类型为SOCK_STREAMTCP。 连接服务器使用connect函数连接到服务器的IP地址和端口号。如果连接成功返回0否则返回错误码。 通信使用已连接的套接字进行数据的发送和接收可以使用read和write函数。 关闭连接当通信结束后使用close函数关闭套接字释放资源。 TCP通信的代码实现 依然是三个文件分别为tcp_server.hpp(用来封装tcp socket)tcp_server.cc(服务器通信代码)tcp_client.cc(客户端通信代码). tcp_server.hpp编写 首先我们要编写tcp_server.hpp首先第一个接口initServer初始化服务端. 一共分为三步 1.创建套接字 利用socket函数创建新的套接字并判断是否成功 listensock socket(AF_INET, SOCK_STREAM, 0);if (listensock 0){logMessage(FATAL, %d:%s, errno, strerror(errno));exit(2);}logMessage(NORMAL, create sock success, listensock: %d, listensock); 2.bind绑定 bind将套接字和特定的ip和地址绑定在一起.用法我们上一章也说了先创建一个sockaddr_in结构体然后填入相关的数据sin_family(协议族 AF_INET(IPv4)或AF_INET6(IPv6)),sin_port(端口号)sin_arr.s_addr(ip地址)然后再bind绑定并判断是否成功代码如下 struct sockaddr_in local;memset(local, 0, sizeof local);local.sin_family AF_INET;local.sin_port htons(_port);local.sin_addr.s_addr _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());if (bind(listensock, (struct sockaddr *)local, sizeof local) 0){logMessage(FATAL, bind error, errno, strerror(errno));exit(3);} 3.listen监听 listen监听是否有新的连接TCP与UDP不同的是当客户端和服务端正式通信的时候需要先建立连接而UDP直接发送数据。所以要listen来监听是否有新链接. 代码如下 // 3.因为TCP是面向连接的意味着当我们正式通信的时候需要先建立连接//第二个参数我们在讲TCP协议时会详细讲解这里先暂且设为20if (listen(listensock, gbacklog) 0){logMessage(FATAL, listen error, errno, strerror(errno));exit(3);}logMessage(NORMAL, init server success); 第二个接口Start()该接口主要负责获取连接并进行通信.共分为两步 accept获取到客户端连接 这个我们同样的需要创建一个sockaddr_in结构体用来存储客户端的连接信息然后接收新的套接字这个套接字是接下来我们通信要使用的。 struct sockaddr_in src;socklen_t len sizeof src;//servicesock(未来真正进行IO) vs listensock(主要任务获取新链接)int servicesock accept(listensock, (struct sockaddr *)src, len);if (servicesock 0){logMessage(ERROR, accept error, errno, strerror(errno));} 通信流程 这里可以提供两个版本的一个是单进程版即每一次只能处理一个客户端. 另一个是 多进程版通过创建子进程来实现对多个客户端处理. 单进程版 紧接着上面说的我们获取到客户端的连接信息后我们需要对其进行解析得到其ip地址和端口号 uint16_t client_port ntohs(src.sin_port);//获得端口号string client_ip inet_ntoa(src.sin_addr);//获得iplogMessage(NORMAL, Link success, %d | %s : %d\n, servicesock, client_ip.c_str(), client_port); 然后直接执行对应的通信函数即可 service(servicesock,client_ip,client_port); 多进程版  利用fork函数实现代码如下后面的服务端通信和客户端通信都不用改动 pid_t id fork();assert(id ! -1);if(id 0){//子进程close(listensock);service(servicesock,client_ip,client_port);exit(0);//僵尸状态}close(servicesock);通信函数service的实现我们从sock中读取消息客户端没有发消息时服务端会阻塞在这里等待用户的输入。 static void service(int sock,const string clientip,const uint16_t clientport) {//echo serverchar buffer[1024];memset(buffer, 0, sizeof(buffer));while(true){//read writessize_t s read(sock,buffer,sizeof buffer-1);if(s 0){buffer[s] 0;//将发过来的数据当做字符串cout clientip : clientport # buffer endl;}else if(s 0)//对端链接关闭{logMessage(NORMAL,%s : %d shutdown, me too!,clientip.c_str(),clientport);break;}else{logMessage(ERROR, read socket error, %d:%s, errno, strerror(errno));break;}write(sock,buffer,strlen(buffer));}close(sock); } tcp_server.cc服务端的编写 这个就很简单了只需要调用initServer初始化和Start开始就行了. #include tcp_server.hpp #include memorystatic void usage(string proc) {cout Usage: proc ServerPort\n endl; }//./tcp_server port int main(int argc, char* argv[]) {if(argc ! 2){usage(argv[0]);exit(1);}uint16_t port atoi(argv[1]);unique_ptrTcpServer svr(new TcpServer(port));svr-initServer();svr-Start();return 0; } tcp_client.cc客户端的编写 创建套接字 int sock socket(AF_INET, SOCK_STREAM, 0);调用connect与服务端链接利用命令行参数将用户输入的ip地址和port端口号获取到然后传入sockaddr_in结构体最后进行connect uint16_t serverPort atoi(argv[2]);string serverIp argv[1]; struct sockaddr_in server;bzero(server, 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) 0) 进行通信(send和recv) TCP的发送和接收消息不同于UDP的sendto和recvfrom而是send和recv。我们分别看一下函数的用法 send ssize_t send(int sockfd, const void *buf, size_t len, int flags); sockfd发送数据的套接字描述符。即想谁发送buf指向要发送数据的缓冲区的指针。len要发送的数据的长度以字节为单位。flags附加选项通常设为0。作用send()函数用于将数据从发送端发送到接收端。它返回已发送的字节数或者在出现错误时返回-1。可以通过设置flags参数来指定传输数据的特定选项例如设置为MSG_DONTWAIT非阻塞发送等。 recv ssize_t recv(int sockfd, void *buf, size_t len, int flags); sockfd要接收数据的套接字描述符。即谁接收buf接收数据的缓冲区的指针。len接收数据的最大长度以字节为单位。flags附加选项通常设为0。作用recv()函数用于从套接字接收数据并将其存储在指定的缓冲区中。它返回接收到的字节数或者在出现错误时返回-1。可以通过设置flags参数来指定接收数据的特定选项例如设置为MSG_DONTWAIT非阻塞接收等。 所以通信代码如下 while (true){string line;cout Please Enter Message# ;getline(cin, line);send(sock, line.c_str(), line.size(), 0);char buffer[1024];ssize_t s recv(sock, buffer, sizeof(buffer) - 1, 0);if (s 0){buffer[s] 0;cout server echo# buffer endl;}else if (s 0){break;}else{break;}} 至此我们的TCP通信就完成了. 当我们使用多进程通信时可以有多个客户端同时向服务端发送消息 至此,TCP的网络通信流程也完成了这是完整的代码可以直接 拷贝运行可去掉logMessage相关的调试信息. 整体代码 注意运行服务器时使用./tcp_server 端口号 运行客户端连接服务器时使用./tcp_clinet 服务器ip 服务器端口号 tcp_server.hpp文件 #pragma once #include iostream #include stdlib.h #include assert.h #include unistd.h #include string.h #include memory #include pthread.h #include signal.h #include cstring #include ctype.h #include sys/types.h #include sys/wait.h #include sys/socket.h #include netinet/in.h #include arpa/inet.husing namespace std;static void service(int sock,const string clientip,const uint16_t clientport) {//echo serverchar buffer[1024];memset(buffer, 0, sizeof(buffer));while(true){//read writessize_t s read(sock,buffer,sizeof buffer-1);if(s 0){buffer[s] 0;//将发过来的数据当做字符串cout clientip : clientport # buffer endl;}else if(s 0)//对端链接关闭{logMessage(NORMAL,%s : %d shutdown, me too!,clientip.c_str(),clientport);break;}else{logMessage(ERROR, read socket error, %d:%s, errno, strerror(errno));break;}write(sock,buffer,strlen(buffer));} }class TcpServer { public:const static int gbacklog 20;TcpServer(uint16_t port, string ip ): _port(port), _ip(ip), listensock(-1){}void initServer(){// 1.创建套接字listensock socket(AF_INET, SOCK_STREAM, 0);if (listensock 0){logMessage(FATAL, %d:%s, errno, strerror(errno));exit(2);}logMessage(NORMAL, create sock success, listensock: %d, listensock);// 2.bindstruct sockaddr_in local;memset(local, 0, sizeof local);local.sin_family AF_INET;local.sin_port htons(_port);local.sin_addr.s_addr _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());if (bind(listensock, (struct sockaddr *)local, sizeof local) 0){logMessage(FATAL, bind error, errno, strerror(errno));exit(3);}// 3.因为TCP是面向连接的意味着当我们正式通信的时候需要先建立连接if (listen(listensock, gbacklog) 0){logMessage(FATAL, listen error, errno, strerror(errno));exit(3);}logMessage(NORMAL, init server success);}void Start(){//version2 :signal(SIGCHLD,SIG_IGN); //对SIGCHLD,主动忽略SIGCHLD信号子进程退出的时候会自动释放自己的僵尸进程while (true){// sleep(1);// 获取连接struct sockaddr_in src;socklen_t len sizeof src;// sock(未来真正进行IO) and _sock(主要任务获取新链接)int servicesock accept(listensock, (struct sockaddr *)src, len);if (servicesock 0){logMessage(ERROR, accept error, errno, strerror(errno));}// 获取连接成功uint16_t client_port ntohs(src.sin_port);string client_ip inet_ntoa(src.sin_addr);logMessage(NORMAL, Link success, %d | %s : %d\n, servicesock, client_ip.c_str(), client_port);// 开始进行通信服务// version 1 -- 单进程循环 -- 只能一次处理一个客户端处理完一个才能处理下一个// 显然是不能被直接使用的为什么单进程.service(servicesock,client_ip,client_port);// version 2 -- 多进程版本 -- 创建子进程// 让子进程给新的连接提供服务子进程能不能打开父进程曾经打开的文件fd呢 答案是当然可以pid_t id fork();assert(id ! -1);if(id 0){//子进程close(listensock);service(servicesock,client_ip,client_port);exit(0);//僵尸状态}//父进程close(servicesock);}}~TcpServer(){}private:uint16_t _port;string _ip;int listensock;unique_ptrThreadPoolTask _threadpool_ptr; }; tcp_server.cc文件 #include tcp_server.hpp #include memorystatic void usage(string proc) {cout Usage: proc ServerPort\n endl; }//./tcp_server port int main(int argc, char* argv[]) {if(argc ! 2){usage(argv[0]);exit(1);}uint16_t port atoi(argv[1]);unique_ptrTcpServer svr(new TcpServer(port));svr-initServer();svr-Start();return 0; } cline.cc文件 #include iostream #include string #include cstdio #include unistd.h #include strings.h #include stdlib.h#include sys/types.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h using namespace std; static void usage(string proc) {cout Usage: proc ServerIP ServerPort endl; } // ./tcp_clinet IP Prot int main(int argc, char *argv[]) {if (argc ! 3){usage(argv[0]);exit(-1);}uint16_t serverPort atoi(argv[2]);string serverIp argv[1];int sock socket(AF_INET, SOCK_STREAM, 0);if (sock 0){cerr sokcet error endl;exit(2);}// client 不需要显式的bindOS会自动选择// 更不需要监听但是需要连接的能力connectstruct sockaddr_in server;bzero(server, 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) 0){cerr connect error endl;exit(3);}cout connect success! endl;while (true){string line;cout Please Enter Message# ;getline(cin, line);send(sock, line.c_str(), line.size(), 0);char buffer[1024];ssize_t s recv(sock, buffer, sizeof(buffer) - 1, 0);if (s 0){buffer[s] 0;cout server echo# buffer endl;}else if (s 0){break;}else{break;}}close(sock);return 0; }
http://www.hkea.cn/news/14432362/

相关文章:

  • 公司网站建设维保协议百度2022年版本下载
  • 有哪些网站可以做笔译开个网站做代理
  • 面对面视频 网站开发旅游网站的网页设计素材
  • 电脑网站手机版怎么做wordpress自定义注册插件
  • 网站怎么制作 优帮云ppt模板下载免费版学生
  • 个人网站建设与实现网站开发要什么基础
  • 企业网站系统建设需求调研表wordpress无法修改电子邮件
  • 英国网站建设做网站建设的有哪些
  • 大淘客网站是怎么做的重庆市制作网站公司哪家好
  • 昆明优化网站公司如何选择镇江网站建设
  • 晚上睡不着正能量网站iis下建多个网站
  • 宁夏建设技术职业学院官方网站学校网站在建设方面的的优势
  • 网站的模糊搜索怎么做网站服务器的费用
  • 商丘网站建设运营公司嘉兴网站seo外包
  • 怎样设置一个属于自己的网站17网站一起做网店东莞
  • 10元建站建筑行业最新资讯
  • 网站内容上传要求什么学做网站
  • dw做网站导航条seo营销的策略有哪些
  • 个人外贸网站建设云南建投二公司官网
  • 外贸网站搭建公司wordpress分类目录加图标
  • 榆林网站建设电话二元期权网站建设
  • 室内设计网站免费模板宠物喂养网页设计模板以及代码
  • 电子商务网站软件建设的核心是什么金融网站模板 html下载
  • crm网站下载江苏常州建设局网站
  • 合肥大型网站设计公温州 网站建设
  • 网站做授权登录个人网页制作怎么做
  • 南通企业网站建设做网站是怎么收费的是按点击率
  • 深圳专业企业网站制作哪家好青岛外贸网站建设哪家好
  • wap网站开发公司图片网站模板下载
  • asp access网站架设教程wordpress安装 用户名已存在