热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TCP网络编程TCPC/S架构socketconnectsendrecvbindlistenaccept三次握手四次挥手多进程实现并发

TCP介绍、编程流程TCP回顾面向连接的流式协议;可靠,出错重传,且每收到一个数据给相应的确认通信之前建立链接服务器被动链接,
TCP 介绍、编程流程

  TCP 回顾


  •         面向连接的流式协议;
  •        可靠,出错重传,且每收到一个数据给相应的确认
  •        通信之前建立链接
    •        服务器被动链接,客户端主动链接

 

 TCP 与 UDP 的差异
 

TCP C/S 架构
 


TCP 编程-socket

    TCP 套接字创建



          UDP 套接字创建回顾
 

int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd <0)
{perror("socket");exit(-1);
}

         创建 TCP 套接字
 

int sockfd;
sockfd &#61; socket(AF_INET, SOCK_STREAM, 0);
if(sockfd <0)
{perror("socket");exit(-1);
}

    做为客户端需要具备的条件


  •        知道“服务器”的ip&#xff0c;port
  •        主动连接“服务器”
  •        用到的函数

                   socket      创建“主动TCP套接字”

                  connect      连接“服务器”

                  send          发送数据到“服务器”

                  recv            接受“服务器”的响应

                  close        关闭连接


TCP 客户端-connect、send、recv

    connect 函数

/**function:* 主动跟服务器建立链接*parameter&#xff1a;* sockfd&#xff1a;socket套接字* addr&#xff1a; 连接的服务器地址结构* len&#xff1a; 地址结构体长度*return&#xff1a;* 成功&#xff1a;0* 失败&#xff1a;其他*note&#xff1a;* connect建立连接之后不会产生新的套接字* 连接成功后才可以开始传输TCP数据
*/
#include int connect(int sockfd, sonst struct sockadr *addr, socklen_t len);

  send 函数
 

/**function&#xff1a;* 发送数据*parameter&#xff1a;* sockfd&#xff1a; 已建立连接的套接字* buf&#xff1a; 发送数据的地址* nbytes&#xff1a; 发送缓数据的大小(字节为单位)* flags&#xff1a; 套接字标志&#xff08;常为0&#xff09;*return&#xff1a;* 成功&#xff1a;发送的字节数*note&#xff1a;* 不能用TCP协议发送 0 长度的数据包*/
#include ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);

recv 函数
 

/**function&#xff1a;* 接收网络数据*paratemer&#xff1a;* sockfd&#xff1a; 套接字* buf: 接收网络数据的缓冲区的地址* nbytes: 接收缓冲区的大小&#xff08;字节为单位&#xff09;* flags: 套接字标志&#xff08;常为0&#xff09;*return:* 成功&#xff1a;接收到字节数*/
#include ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

 

客户端 code

#include
#include
#include
#include
#include
#include
#include int main(int argc, char *argv[])
{unsigned short port &#61; 8000; //服务器的端口号char *server_ip &#61; "172.20.226.11"; //服务器的IP//给main传参if(argc > 1) //函数参数&#xff0c;可以改服务器IP{server_ip &#61; argv[1];}if(argc > 2) //函数参数&#xff0c;可以改服务器端口号{port &#61; atoi(argv[2]);}//创建TCP套接字int sockfd &#61; 0;sockfd &#61; socket(AF_INET, SOCK_STREAM, 0); //创建通行端点&#xff1a;套接字if(sockfd <0){perror("socket");exit(-1);}//设置连接的IP&#xff0c;端口struct sockaddr_in server_addr;bzero(&server_addr, sizeof(server_addr)); //初始化服务器的地址server_addr.sin_family &#61; AF_INET;server_addr.sin_port &#61; htons(port);inet_pton(AF_INET, server_ip, &server_addr.sin_addr);//连接服务器int err_log &#61; connect(sockfd, (struct sockaddr *)&server_addr,sizeof(server_addr));if(err_log !&#61; 0){perror("connect");close(sockfd);exit(-1);}char send_buf[512] &#61; "";char recv_buf[512] &#61; "";printf("send data to %s&#xff1a;%d \n", server_ip,port);//发送消息printf("send");fgets(send_buf, sizeof(send_buf), stdin);send_buf[strlen(send_buf) - 1] &#61; 0; //除去‘\n’send(sockfd, send_buf, strlen(send_buf), 0); //向服务器发送数据//接收数据recv(sockfd, recv_buf, sizeof(recv_buf), 0); //接受服务器的响应printf("recv: %s \n",recv_buf);close(sockfd);}



TCP 服务器-bind、listen、accept

     做为 TCP 服务器需要具备的条件


  •       有一个确定的地址
  •        操作系统知道一个服务器
  •       等待连接的到来

   对于面向连接TCP协议来说&#xff0c;连接的建立才是数据通信的开始


      bind 示例

int err_log &#61; 0;
unsigned short port &#61; 8000;
struct sockaddr_in my_addr;bzero(&muy_addr, sizeof(my_addr));
my_addr.sin_family &#61; AF_INET;
my_addr.sin_port &#61; htons(port);
my_addr.sin_addr.s_addr &#61; htonl(INADDR_ANY);err_log &#61; bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if(err_log !&#61; 0)
{perror("binding");close(sockfd);exit(-1);
}

      listen 函数

/*
功能:套接字由主动改为被动操作系统为套接字设置一个连续队列&#xff0c;用来记录所有连接到该套接字的连接参数&#xff1a;sockfd&#xff1a;socket监听套接字backlog&#xff1a;连接队列的长度返回值&#xff1a;成功&#xff1a;返回 0失败&#xff1a;其他
*/
#include int listen(int sockfd, int backlog);

     accept 函数

/*
功能&#xff1a;从已连接队列中取出一个已经建立的连接&#xff0c;如果没有任何连接可用&#xff0c;则进入睡眠等待&#xff08;阻塞&#xff09;参数&#xff1a;sockfd&#xff1a;socket 监听套接字cliaddr&#xff1a;用于存放客户端套接字地址结构addrlen&#xff1a;套接字地址结构体长度的地址返回值&#xff1a;已连接套接字注意&#xff1a;返回的是一个已连接套接字&#xff0c;该套接字代表当前这个连接*/
#include int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

      TCP 服务器例子
 

#include
#include
#include
#include
#include
#include
#include int main(int argc, char *argv[])
{unsigned short port &#61; 8000;if(argc > 1){port &#61; atoi(argv[1]);}//创建TCP套接字int sockfd &#61; socket(AF_INET, SOCK_STREAM, 0);if(sockfd <0){perror("socket");exit(-1);}//组织本地信息struct sockaddr_in my_addr;bzero(&my_addr, sizeof(my_addr));my_addr.sin_family &#61; AF_INET;my_addr.sin_port &#61; htons(port);my_addr.sin_addr.s_addr &#61; htonl(INADDR_ANY);//绑定信息int err_log &#61; bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));if(err_log !&#61; 0){perror("binding");close(sockfd);exit(-1);}//“主动”变“被动”err_log &#61; listen(sockfd, 10);if(err_log !&#61; 0){perror("listen");close(sockfd);exit(-1);}printf("listen client &poort &#61; %d...\n",port);while(1){struct sockaddr_in client_addr;char cli_ip[INET_ADDRSTRLEN] &#61;"";socklen_t cliaddr_len sizeof(client_addr);int connfd;//等待连接的到来connfd &#61; accept(sockfd, (struct sockaddr *)&client_addr, &cliaddr_len);if(connfd <0){perror("accept");continue;}//转换并打印信息inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);printf("--------------------------------\n");printf("client ip &#61; %s, port &#61; %d\n",cli_ip, ntohs(client_addr.sin_port));char recv_buf[2048] &#61; "";//接收消息while(recv(connfd, recv_buf, sizeof(recv_buf), 0) > 0){printf("\n recv data: \n");printf("%s\n",recv_buf);}close(connfd); //关闭已连接的套接字printf("client closed \n");}close(sockfd); //关闭监听的套接字return 0;
}


TCP 编程-close、三次握手、四次挥手

   close 关闭套接字


  •        使用close函数关闭套接字

                 关闭一个代表已连接套接字将导致另一端接收到一个0长度的数据包

  •        做服务器时

                    1      关闭监听套接字将导致服务器无法接收新的连接&#xff0c;但不影响已建立的连接

                    2     关闭accept返回已连接套接字将导致它代表的连接被关闭&#xff0c;但不会影响服务器的监听

  •        做客户端时

                 关闭连接就是关闭连接&#xff0c;不意味着其他

     三次握手

 


     四次挥手



TCP 并发服务器


     多进程实现并发

//#include <头文件>int main(int argc, char *argv[])
{//创建套接字sockfd//绑定&#xff08;bind&#xff09;套接字sockfd//监听&#xff08;listen&#xff09;套接字sockfdwhile(1){int connfd &#61; accept();if(fork() &#61;&#61; 0) //子进程{close(sockfd); //关闭监听套接字sockfdfun(); //服务客户端的具体事件在fun里实现close(connfd); //关闭已连接套接字connfdexit(0); //结束子进程}close(connfd); //关闭已连接套接字connfd}close(sockfd);return 0;
}

 


  多线程实现并发

//#include<头文件>int main(int argc, char *argv[])
{//创建套接字sockfd//绑定&#xff08;bind&#xff09;套接字sockfd//监听&#xff08;listen&#xff09;套接字sockfdwhile(1){int connfd &#61; accept();pthread_t tid;pthread_create(&tid, NULL, (void *)client_fun, (void *)connfd);pthread_detach(tid);}close(sockfd); //关闭监听套接字return 0;
}void *client_fun(void *arg)
{int connfd &#61; (int) arg;fun(); //服务与于客户端的具体程序close(connfd);
}


Web 服务器介绍

    web 服务器简介

         web服务器&#xff1a;

                www服务器&#xff0c;网站服务器

           特点&#xff1a;

                  使用HTTP协议与客户机浏览器进行信息交流

                 不仅存储信息&#xff0c;还可以在用户通过web浏览器提供的信息的基础上运行脚本和程序

                 该服务器可安装在UNIX&#xff0c;Linux&#xff0c;Windows等操作系统上

                著名的服务器有Apache&#xff0c;Tomcat&#xff0c;IIS

       HTTP 协议

             webserver    HTTP协议

                概念

                   一种详细规定了浏览器和万维网服务器之间互相通信的规则&#xff0c;通过因特网传送万维网文档的数据传送协议

               特点

  •            支持C/S架构
  •            简单快速&#xff1a;客户向服务器请求服务时&#xff0c;只传送请求方法和路径&#xff0c;常用GET&#xff0c;POST
  •            无连接&#xff1a;限制每次连接只处理一个请求
  •            无状态&#xff1a;如果后续处理需要前面的信息&#xff0c;它必须重传&#xff0c;这样可能导致每次连接传送的数据量增大

 

    Webserver 通信过程
 

 
 

 

推荐阅读
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
author-avatar
aloneloveu2005
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有