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

品牌网站建设 蝌4蚪小网站后台怎么用ftp打开

品牌网站建设 蝌4蚪小,网站后台怎么用ftp打开,网页设计需要考什么证书,互联网产品设计最基本的Socket编程 想客户端和服务器能在网络中通信,就得使用 Socket 编程,它可以进行跨主机间通信。在创建Socket时可以选择传输层使用TCP还是UDP。相对于TCP来说,UDP更为简单,下面以TCP为例。 TCP服务端要先建立起来&#xf…

最基本的Socket编程

想客户端和服务器能在网络中通信,就得使用 Socket 编程,它可以进行跨主机间通信。在创建Socket时可以选择传输层使用TCP还是UDP。相对于TCP来说,UDP更为简单,下面以TCP为例。

TCP服务端要先建立起来,等待客户端的连接到来,然后建立起连接。

1、服务端首先调用socket()函数,创建套接字,

2、接着调用bind()函数来绑定IP和地址和端口号。

绑定 IP 地址:一台机器是可以有多个网卡的,每个网卡都有对应的IP 地址,只有当绑定了目标网卡时,内核在收到该网卡上的数据包,才会发给我们。

绑定端口:当内核收到 TCP 报文,通过 TCP 头里面的端口号,来找到我们的应用程序,然后把数据传递给对应端口号的程序。

3、调用listen()函数将创建的套接字设为监听状态,刚刚创建的套接字为监听套接字,即这个套接字只是用来监视有没有客户端发起新连接,并不进行真正的通信。

4、服务端进入了监听状态后,通过调用accept()函数,来从内核获取客户端的连接,如果没有客户端连接,则会阻塞等待客户端连接的到来。

相关代码如下:

            // 1.创建套接字_listensock = socket(AF_INET, SOCK_STREAM, 0);if(_listensock < 0){exit(2);}cout << "create socket success" << endl;// 2.绑定struct 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 = bind(_listensock, (struct sockaddr*)&local, sizeof(local));if(n_bind < 0){exit(3);}cout << "bind socket success" << endl;// 3.监听,设置套接字socket状态为监听状态int n_listen = listen(_listensock, 5);if(n_listen < 0){exit(4);}cout << "listen socket success" << endl;

接下来就是TCP客户端:客户端创建socket,然后调用connect()函数发起连接,并且在connect的时候要指明服务器的IP和端口号;当发起connect后,就开始三次握手过程建立连接,成功后会返回一个文件描述符,是和服务端建立好连接的,然后双方就能进行通信了。

相关代码如下:

        void InitClient(){// 1. 创建socket_sock = socket(AF_INET, SOCK_STREAM, 0);if(_sock < 0){exit(2);}// 2. tcp的客户端要不要bind?要的! 要不要显示的bind?不要!这里尤其是client port要让OS自定随机指定!// 3. 要不要listen?不要!// 4. 要不要accept? 不要!// 5. 要什么呢??要发起链接!}void Start(){// 发起链接,使用connect// 首先要知道要链接的服务端的ip和portstruct sockaddr_in server;bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(_serverip.c_str());server.sin_port = htons(_serverport);int n_connect = connect(_sock, (struct sockaddr*)&server, sizeof(server));if(n_connect < 0){cout << "socket connect error" << endl;}else{string message;while(true){cout << "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; }}}}

在 TCP 连接的过程中,服务器的内核实际上为每个 Socket 维护了两个队列:
一个是尚未完全建立起连接的队列,称为 TCP 半连接队列,这个队列都是没有完成三次握手的连接,此时服务端处于syn_rcvd 的状态;
一个是已经建立连接的队列,称为 TCP 全连接队列,这个队列都是完成了三次握手的连接,此时服务端处于 established 状态;
当 TCP 全连接队列不为空后,服务端的 accept()函数,就会从内核中的 TCP 全连接队列里拿出一个已经完成连接的 socket 返回应用程序,后续数据传输都用这个 socket。

需要注意的是:监听连接到来的socket和真正通信的socket是不同的

连接建立后,客户端和服务端就开始相互传输数据了,双方都可以通过 read()和 write()函数来读写
数据。

上面所描述的TCP Socket是最简单的,基本只能用来一对一通信,其使用的是同步阻塞的方式,当服务端在还没处理完一个客户端的网络 I/0 时,其他客户端是无法与服务端连接的。但是一个服务器只服务一个客户,这样就太浪费资源了,所以要进行改进:

多进程模型:

服务器的主进程负责监听客户的连接,一旦与客户端连接完成,这时当前进程就通过 fork()函数创建一个子进程,实际上就把父进程所有相关的东西都复制一份,包括文件描述符、内存地址空间、执行的代码等。
因为子进程会复制父进程的文件描述符,于是就可以直接使用已连接 Socket和客户端通信了,可以发现,子进程不需要关心监听 Socket,只需要关心已连接 Socket;父进程则相反,将客户服务交给子进程来处理,因此父进程不需要关心已连接 Socket,只需要关心监听 Socket。

这里需要注意的是要回收子进程,否则会造成僵尸进程的问题,最终导致资源泄漏的问题。这种用多个进程来应付多个客户端的方式,当客户端数量很多时,肯定是扛不住的,因为每产生一个进程,必会占据一定的系统资源,而且进程间上下文切换代价也不小,性能会有很大的影响。所以又有了多线程版本:

多线程模型:

在Linux中线程是更加轻量化的进程,是CPU调度的基本单位,并且线程切换相比于进程切换代价更小,性能会更好,当服务器与客户端 TCP 完成连接后,通过 pthread create()函数创建线程,然后将已连接 Socket的文件描述符传递给线程函数,接着在线程里和客户端进行通信,从而达到并发处理的目的。
如果每来一个连接就创建一个线程,线程运行完后,还得操作系统还得销毁线程,虽说线程切换的上写文开销不大,但是如果频繁创建和销毁线程,系统开销也是不小的。
那么,我们可以使用线程池的方式来避免线程的频繁创建和销毁,所谓的线程池,就是提前创建若干个线程,这样当由新连接建立时,将这个已连接的 Socket 放入到一个队列里,然后线程池里的线程负责从队列中取出已连接 Socket 进行处理。

相关代码如下:

        void Start(){// 初始化线程池并启动线程池ThreadPool<Task>::getInstance()->run();cout << "Thread init success" << endl;// 4.acceptwhile(1){struct sockaddr_in peer;socklen_t len = sizeof(peer);// accept成功返回一个文件描述符,用来和Client通信,而这里的_sock是用来监听链接到来,获取新链接的。int sock = accept(_listensock, (struct sockaddr*)&peer, &len);if(sock < 0){continue;}cout << "accept a new link success, get new sock: " <<  sock << endl;// 5.这里就是一个sock,未来通信我们就用这个sock,面向字节流的,后续全部都是文件操作!// version 1//serviceIO(sock);//close(sock); //对一个已经使用完毕的sock,我们要关闭这个sock,要不然会导致,文件描述符泄漏// version 2 多进程// pid_t id = fork();// if(id == 0) // 子进程// {//     // 子进程会有自己独立的进程地址空间//     close(_listensock);//     if(fork() > 0) exit(0);//     serviceIO(sock);//     close(sock);//     exit(0);// }// close(sock);// // 父进程// // 子进程结束需要父进程来回收,避免僵尸进程// pid_t ret = waitpid(id, nullptr, 0);// if(ret>0)// {//     std::cout << "waitsuccess: " << ret << std::endl;// }// version 3 多线程// pthread_t tid;// ThreadData* td = new ThreadData(this, sock);// pthread_create(&tid, nullptr, threadRoutine, td);// version 4 线程池ThreadPool<Task>::getInstance()->push(Task(sock, serviceIO));}}

上面的代码是部分代码,具体的代码可以通过下面链接查看:

Linux: Linux学习 - Gitee.com

http://www.dtcms.com/a/584499.html

相关文章:

  • 橄榄树网站建设性价比最高的网站建设公司
  • 杭州小型网站建设服务做的王者荣耀钓鱼网站
  • 购物网站 建站服务黑龙江今天的新消息
  • python做简单网站中国电力工程造价信息网
  • 郴州公司网站建设鄂温克族网站建设
  • 网站开发公司照片织梦网站如何做关键词
  • 怎么使用源码建设网站wordpress首页文件夹
  • 开装潢公司做网站电脑上买wordpress
  • 商务网站建设与推广实训报告如何更换网站新域名
  • 网站后台管理系统制作教程用vs做网站界面
  • 如何设计网站的链接广告公司名字大全免费
  • ps做专业网站做网站对服务器要求
  • 人工智能自动做网站上海正规建设网站私人订制
  • 化妆品品牌网站如何做最好的淘宝网站建设
  • 嘉兴 网站 建设wordpress如何更改登录地址
  • 上海微信网站公司株洲人才网官网
  • 常州微信网站建设方案旅游网站 建设平台分析
  • excel做网站链接网络舆情
  • 贵溪市城乡建设局网站免费域名注册可解析
  • 阿里云服务器架设网站青海西宁网站建设
  • 网站打不开怎么回事手机开发者选项在哪里打开
  • 网站开发需要资质吗网站seo关键词优化
  • 游戏网站开发网络规划设计师教程第2版高清下载
  • 潍坊市建设工程管理处网站深圳搜豹网站建设公司
  • 海尔电子商务网站建设天元建设集团有限公司证券
  • 做视频添加字幕的网站不备案如何架设网站
  • 天津市网站建设 网页制作广东东莞出行最新政策
  • 做旅游的网站的目的和意义最常用的网站推广方式
  • 北碚区网站建设个人网站可以做推广吗
  • 宁夏网站建设公司湖南人文科技学院学费