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

做链接哪个网站好宁波优化网站哪家好

做链接哪个网站好,宁波优化网站哪家好,营销型网站建设页面,网站建设和维护要点前文:Socket套接字编程 TCP的特点 面向连接:TCP 在发送数据之前,必须先建立连接。可靠性:TCP 提供了数据传输的可靠性。面向字节流:TCP 是一个面向字节流的协议,这意味着 TCP 将应用程序交下来的数据看成是…

前文:Socket套接字编程

TCP的特点

  • 面向连接:TCP 在发送数据之前,必须先建立连接。
  • 可靠性:TCP 提供了数据传输的可靠性。
  • 面向字节流:TCP 是一个面向字节流的协议,这意味着 TCP 将应用程序交下来的数据看成是一连串的无结构的字节流。

TcpServer.hpp

创建一个Tcp服务端
在这里插入图片描述

代码

#pragma once#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<cstring>
#include<arpa/inet.h>
#include<unistd.h>
#include <sys/wait.h>
#include<functional>
#include<pthread.h>
#include"InetAddr.hpp"
#include"Log.hpp"
#include"Threadpool.hpp"enum
{SOCKET_ERROR = 1,BIND_ERROR,LISTEN_ERROR,USAGE_ERROR
};const static int defaultsockfd = -1;//默认文件描述符
const static int gbacklog = 16;//默认最大连接数using task_t=std::function<void*()>; //任务函数的类型(V3)
class TcpServer;
//线程类型数据
class ThreadData
{
public:ThreadData(int fd,InetAddr addr,TcpServer* s):sockfd(fd),clientaddr(addr),self(s){}
public:int sockfd;//文件描述符InetAddr clientaddr;//客户端地址TcpServer* self;//服务端
};
class TcpServer
{
public:TcpServer(int port):_port(port),_listensock(defaultsockfd),_isrunning(false){}void InitServer(){//1.创建字节流套接字_listensock=socket(AF_INET,SOCK_STREAM,0);if(_listensock<0){LOG(FATAL, "socket error");exit(SOCKET_ERROR);}LOG(DEBUG, "socket create success, sockfd is : %d\n", _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=INADDR_ANY;int n= ::bind(_listensock,(struct sockaddr*)&local,sizeof(local));if(n<0){LOG(FATAL, "bind error\n");exit(BIND_ERROR);}LOG(DEBUG, "bind success, sockfd is : %d\n", _listensock);//3.监听客户端,等待被连接n=listen(_listensock,gbacklog);if(n<0){LOG(FATAL, "listen error");exit(LISTEN_ERROR);}LOG(DEBUG, "listen success, sockfd is : %d\n", _listensock);}//将接收到的数据进行处理,完成对应服务void Service(int sockfd,InetAddr client){LOG(DEBUG, "get a new link, info %s %d ,fd: %d \n ",client.Ip().c_str(),client.Port(),sockfd);std::string clientaddr = "[" + client.Ip() + ":" + std::to_string(client.Port()) + "]# ";while(true){char inbuffer[1024];ssize_t n = read(sockfd,inbuffer,sizeof(inbuffer)-1);//读取数据if(n>0){inbuffer[n]=0;std::cout<<clientaddr<<inbuffer<<std::endl;//打印对应的数据std::string echo_string = "[server echo]# ";echo_string+=inbuffer;write(sockfd,echo_string.c_str(),echo_string.size());//返回给客户端}else if(n==0) //client退出并且关闭连接了{LOG(INFO, "%s quit\n", clientaddr.c_str());break;}else{LOG(ERROR, "read error\n");break;}}close(sockfd);        }//线程的处理函数static void* HandlerSock(void* args){pthread_detach(pthread_self());//线程分离ThreadData* td=static_cast<ThreadData*>(args);//创建对应线程数据类型td->self->Service(td->sockfd,td->clientaddr);delete td;return nullptr;}//服务器循环运行着void Loop(){_isrunning=true;while(_isrunning){struct sockaddr_in peer;//sock地址peersocklen_t len=sizeof(peer);//要先通过连接才能够进行通信int sockfd=::accept(_listensock,(struct sockaddr *)&peer,&len);//这里的监听sock和sockfd是不同的if(sockfd<0){LOG(WARNING, "accept error\n");continue;}//Version0 这种版本只能接收一次需求,无法多客户端连接// Service(sockfd,InetAddr(peer));//Version1 多进程// pid_t id=fork();// if(id>0)// {//     //子进程负责连接,父进程负责监听,//     close(_listensock);//     if(fork()>0) exit(0);//     //孙进程负责服务,由于子进程连接之后,子进程会进行回收,因此孙进程称为孤儿进程,之后不受子进程的影响//     //类似线程分离,是独立的,之后受系统进行回收//     Service(sockfd,InetAddr(peer));//     exit(0);// }// //父进程只负责监听,不需要进行连接// close(sockfd);// waitpid(id,nullptr,0);//Version2:采用多线程pthread_t t;ThreadData* td=new ThreadData(sockfd,peer,this);pthread_create(&t,nullptr,HandlerSock,td);//将线程分离//Version3:线程池//task_t t = std::bind(&TcpServer::Service,this,sockfd,InetAddr(peer));//ThreadPool<task_t>::GetInstance()->Enqueue(t);}_isrunning=false;}~TcpServer(){if(_listensock>defaultsockfd){close(_listensock);}}private:uint16_t _port;//端口号int _listensock;//监听的文件描述符bool _isrunning;//启动
};

解释

在这里插入图片描述
初始化服务端,主要完成套接字的创建绑定,已经完成对应的监听客户端,因为Tcp是有连接的,所以需要监听客户端是否有请求连接的需求;
SOCK_STREAM表示字节流

gbacklog:这个参数定义了内核应该为相应套接字排队的最大连接数。这个值至少为0;其实际值由系统限制,可以通过sysctl命令的net.core.somaxconn参数查看和设置。需要注意的是,这个值并不是指系统能处理的并发连接数,而是内核中等待accept(处理的连接队列的最大长度

在这里插入图片描述
启动服务器之后,通过循环让服务端不断运行着,在循环里面,服务端可能接收到多个客户端请求的连接,所以accpet要在循环中不断接收看是否有对应的连接;

连接完之后通过Service服务函数完成双方的通信
在这里插入图片描述
在Loop中,循环表示接收多个客户端,而Service中,循环表示每个服务端与客户端的通信保持;
由于tcp是面向字节流的,所以可以利用文件描述符的性质,运用read函数,读取对应的发送端数据.
当n大于0时,表示对方有数据发送,处理完信息后反馈给对方;
当n==0,表示sockfd被关闭了,也就是连接被断开了;
当n小于0时,表示出现错误;
如果一直没有发送数据,那么会在read函数这里发生阻塞

在这里插入图片描述
而对于服务的处理,这里有多种方法,如果直接使用Service函数的话,是不可行的,因为这样无法多客户端连接:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过多进程的方法,让父进程只负责监听,子进程负责连接,孙进程负责服务,由于孙进程是孤儿进程,相当于线程分离,这样处理服务时就不会受到父子进程的影响了;也就能完成多客户端的通信了;

在这里插入图片描述
直接通过多线程的方法,将创建的线程进行分离,完成对应的服务任务

main.cc

#include"TcpServer.hpp"
#include<memory>void Usage(std::string proc)
{std::cout << "Usage:\n\t" << proc << " local_port\n" << std::endl;
}
// ./main.cc 8080
int main(int argc,char* argv[])
{if(argc!=2){Usage(argv[0]);return 1;}EnableScreen();//打印到屏幕uint16_t port=std::stoi(argv[1]);//获取端口号std::unique_ptr<TcpServer> tsvr=std::make_unique<TcpServer>(port);//服务端的指针tsvr->InitServer();//初始化tsvr->Loop();//循环运行return 0;}

TcpClient.cc

#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>
#include<cstring>void Usage(std::string proc)
{std::cout << "Usage:\n\t" << proc << " serverip serverport\n"<< std::endl;
}
// ./TcpClient.cc 127.0.0.1 8080
int main(int argc,char* argv[])
{if(argc!=3){Usage(argv[0]);exit(1);}std::string serverip=argv[1];//服务端ipuint16_t serverport=std::stoi(argv[2]);//服务端端口号int sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建套接字if (sockfd < 0){std::cerr << "socket error" << std::endl;exit(2);}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());//连接服务端int n=connect(sockfd,(struct sockaddr*)&server,sizeof(server));if(n<0){std::cerr << "connect error" << std::endl;exit(3);}while(true){std::cout<<"Please Enter# ";std::string outstring;getline(std::cin,outstring);//发送对应数据ssize_t s=send(sockfd,outstring.c_str(),outstring.size(),0);if(s>0){char inbuffer[1024];ssize_t m=recv(sockfd,inbuffer,sizeof(inbuffer)-1,0);//接收对应数据if(m>0){inbuffer[m]=0;std::cout<<inbuffer<<std::endl;}else{break;}}else{break;}}close(sockfd);return 0;
}

结果

在这里插入图片描述

http://www.hkea.cn/news/4736/

相关文章:

  • 网站访问量突然增加搜索引擎优化是指
  • 网购网站开发流程图大数据精准获客软件
  • app下载安装官方网站如何让百度收录网址
  • 湖北武汉网站制作长沙网站推广智投未来
  • 社保网站做的真烂查域名ip地址查询
  • 西安网站设计公司排名收录优美的图片app
  • 网站ipv6改造怎么做专业的seo搜索引擎优化培训
  • 做网站武汉首选福州外包seo公司
  • 陕西西安网站建设新媒体运营岗位职责
  • 重庆做网站设计免费放单平台无需垫付
  • 济南高新区 网站建设百度推广客户端mac版
  • 网上有做任务赚钱的网站有哪些自己开发网站
  • 投标网站建设服务承诺今日小说搜索风云榜
  • 香港做网站找谁兰州网络推广技术
  • 佛山宽屏网站建设建站推广
  • 深圳网站建设策划太原seo关键词排名优化
  • 乌托邦网站建设快速排名软件案例
  • 主机屋vps网站助手销售清单软件永久免费版
  • 博客系统做网站企业网站营销
  • 塑胶原料 东莞网站建设独立站seo搜索优化
  • web 设计网站模板下载重庆百度竞价开户
  • html表白简单代码宁波seo深度优化平台
  • 陕西省建设厅网站首页邮件营销
  • 网站开发工作周记天津百度
  • 网站的营销特点怎么营销推广
  • 聊城正规网站建设设计公司软文广告属于什么营销
  • 湖南建筑公司网站排名优化哪家专业
  • 复兴企业做网站推广yande搜索引擎官网入口
  • 基于.net平台网站内容管理系统研究与实现搜一搜百度
  • 建立公司网站需要注意什么图片搜索