TCP通信备忘

1.    http请求,每个请求都是一个socket TCP连接,不同请求之间不会占用同一个tcp通道,
      不会出现同一个tcp通道,多个请求多线程访问的情况。

2.   每个请求都是单独的一个socket 发生请求,并挂起,等待返回结果,此时是在一个线程中,
      此时返回的socket的inputstream中的内容就是当前请求,当前线程的返回内容。

3.   http keepalive 是tcp通道的重复使用,一个http请求,占用tcp的socket,发完请求后不再占用这个通道。

     下一个http发起请求,独占这个通道,不会出现多个请求同时使用;

      同一个页面中的多个请求,或者下一个页面,

      由于请求的服务器很可能相同,会重复使用这个tcp通道。

       这个tcp通道的请求,返回结果即只是这一个http请求的返回内容,不需要去识别不同的http请求。

4.    在停车场tcp 连接后,服务器和停车场的这个Tcp socket通道,会被多线程访问,
        而不是http请求的一个线程独占。

        因为,服务器是http的,每个浏览器页面发生请求,被tomcat接受后,都会形成单独的线程,

        多个线程都通过这个tcp通道,发送请求到停车场。这时候,多线程并发写入outputstream

        会造成错乱,所以加多线程同步锁,获取锁的线程发送请求,并读取返回内容,

        没有返回内容时挂起,等待返回内容。哪个线程获取锁,发生请求了,

        就由该线程调用socket通道的inputstream一直挂起,直到有返回结果后,

        这个返回结果就肯定是当前这个线程的,然后释放锁,不再占用tcp通道。

5.     http服务器接受请求后,启动一个线程,占用tcp通道发送请求,然后等待返回内容。

        这是一个单向的请求返回逻辑,不能是双向的即当前线程发送请求后,

        收到的返回内容应该就是针对这个请求的回复,而如果是双向即收到的内容是其他业务逻辑,

         比如生成一个文件,那么就需要启动一个新线程去处理,并把处理后的结果返回,

         同时当前线程还要继续等待。新线程处理完后,返回内容也是要进行同步就很复杂了。

6.      上一条的根本原因是,http请求是多线程的,每个线程都需要有一个返回结果,

          线程收到返回结果后就退出,这多个线程之前都是隔离的,因为可能是不同的浏览器和不同的请求。

          而对于桌面应用,比如Android来说,请求都是由UI线程发起的,虽然不同的按钮点击都启动新的线程,

          但是都是通过handler把UI线程和新启动的请求线程之间连接起来,

          每个请求的结果都通过handler发送到UI线程中,UI线程是显示界面的,一直处于运行中,

          多个请求的结果通过handler加入到消息队列中,防止多个请求线程更改UI线程中的内容,

           造成同步问题。多个请求的最后返回结果的处理,都是在UI线程中,

           所以欧冠的程序可以不用加锁独占通道,而且可以双向通信,因为多线程请求的返回结果

           都是在UI线程中显示并处理,根据返回内容来更改界面和文字,显示结果。

           这个http请求有本质的不同,http请求每个请求都是一个线程,这个线程需要明确的返回内容,

           并且会退出,所以如果不加锁独占tcp通道的话,由一个线程读取返回的内容,

           那么就要判断是哪个线程的返回内容,唤醒通知,退出线程,双向通信还要启动新的线程并管理,

           就因为http请求是多个线程并且最终返回的时候也是不同线程间独立的返回,共用通道的话,

           就需要明确的管理和通知不同的线程,双向通信的话还要启动新的线程进行处理,过于复杂。

7.       不同线程间的通信,使用handler匿名内部类。多线程并发更改UI线程的内容时,

          使用队列来解决,比加锁应该性能更好,例如Android中的handler的消息队列。

8.       桌面程序始终显示界面,相当于Android的UI线程,是一直存在的,

 
          socket收到的信息最终都在UI线程的界面上处理,根据返回的id和内容进行处理, 

 
          而Http服务和这个有明显区别,每个页面的http服务都是一个线程,每个线程都要单独的返回给浏览器,


          这个过程中时没有一个UI界面类似的线程统一处理返回结果的,socket通信获取的内容,


          必须识别出是哪个请求对应哪个线程,找到这个线程并唤醒,发送结果然后返回浏览器,线程退出,


           多线程请求,为了识别出每个线程对应的返回结果,导致必须独占通道,

           
           而双向通信又会导致新的线程启动和管理,所以必须是单向,

           
           当然上面的处理是为了每个http请求页面都能有一个明确的处理返回内容,

           
           如果不需要一个明确的成功失败,也可以把多线程内容放入到队列中,使用同一一个线程,


            就不会存在多线程管理的问题,就可以用你之前的那种双向通信,并且不需要加锁来独占通道,


            websocket 和桌面程序类似,只有一个浏览器页面,不会多线程共用通道,

            
            因为所有返回结果都在页面html上判断和显示,类似UI线程,有返回内容就处理显示,可以双向通信。
==========================================================================================
 

2016-12-13 更新补充:


tomcat  和浏览器对http的实现也是每次请求新建tcp通道,不同请求互相不干扰也无法访问,而且请求是同步请求,

tomcat也是每个请求独立的线程和对象,方法进行处理,并没有对不同请求进行获取和返回时选择某个请求的线程去主动调用这个线程去返回结果,

这样大大简化设计

而且即使是websocket保持了客户端和服务器的长连接,也没有用这个长连接同时发送http请求,

因为每个http请求是同步的而且无法管理不同的http线程去调用和通知,http是每个线程不被记住,

自动主动同步请求并等待返回结果,而想同时接受服务端的tcp请求并返回结果时,

需要一直占用通道并保持监听,会导致太过复杂,

所以websocket只用于tcp通信而没有同时作为http请求通道,停车场的tcp也只是单向的

 
 
想了下,可以用blockingQueue  
new ArrayBlockingQueue(1)

启动一个线程while((data=socket.read()) !=null)监听,
 
  
当socket返回的内容为tcp主动推送时,调用对应方法,返回响应;
 
  
当为返回的是http请求的response时,put到queue中,
 
  
每个http 请求调用socket发送请求时加同步锁,同时调用queue.take();当不是返回的response时,继续take()阻塞;
 
  
但还是复杂。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值