socket相关


摘抄:blog.youkuaiyun.com/huazhihao/archive/2009/06/18/4278699.aspx

从头开始构建一个web即时通讯系统 - 基础 - web即时通讯系统的四种实现

 

页面刷新

页面刷新即通过刷新页面来更新聊天记录,通过页面提交来发送消息。毫无疑问,这种实现是最简单的,也是效率最差的。它意味着每一次收发消息都对应了一次httprequest,而http作为应用层协议,连接代价是相当大的。

ajax

ajax可以理解为xmlhttprequest,本质与页面刷新相同,但是页面上会有很多资源文件,比如图片、css、js、flash,这些文件会随着页面刷新并且没有做浏览器端缓存的时候更新。为了接收或者发送数十字节的消息而更新可能多达数百K字节的字节文件,显然是很愚蠢的。所以使用ajax来通讯,"只"需要为消息的获取或者发送而进行请求。ajax从这一点上是优于页面刷新的。

comet/server push

ajax为每一个消息的发送和接收建立一个新的http连接,并在短暂通讯完毕以后关闭。而server push的本质是http长连接,它的思路是,让服务器和浏览器维持着一个时间跨度很长的http连接,这个http连接可能大部分时候并不需要做什么,只在有消息的时候,向浏览器写入。所以这种方式避免了建立以及关闭http连接时大量的开销,提高了资源利用率。不过server push也有它的问题,在一个web服务器上,http连接数并非没有限制,所以如果把http连接数也看作是系统资源的话,server push确实是对于此资源的极大浪费了。

comet是server push的思路上的一种改进,它在ajax和server push之间使用了一种折中的策略,在高频率的通讯过程中,comet使用http长连接。一旦通讯变得不频繁,comet便释放http连接,并在下一次通讯的时候,是情况而定,看是否需要建立http长连接。

server push在asp.net中可以通过下面的代码片段实现:

        protected void Page_Load(object sender, EventArgs e)

        {

            while (IsSessionEnd as bool)

            {

                lock (token as object)

                {

                    Response.Write(message as string);

                    Response.Flush();

                }

            }

        }

(当然,在实际编码中,as type的写法是不必要的,这里只是为了说明类型)

可以看到,在上面的代码片段中,会话结束前,Response.End()都不会被调用。

socket/tcp

在页面刷新、ajax和server push的思路里,最重要的一个共同点就是基于http。http是web的基础,然而http并不符合即时通讯系统的思想,很大程度上是由于http几个特点:

[

  http是无状态的,

  http是一问一答的,

  http是单播的,

  http是应用层协议,通讯代价很大

]

然而http的下层协议tcp/udp就很适合用来做为即时通讯系统的通讯协议。可是在web标准里,一切都是基于http的。幸运的是,我们可以通过浏览器插件的信路来完成通讯,在java applet、flash和silverlight里,都提供了socket/tcp,并且dom和flash或silverlight是可以互操作的。这就意味着,dom也可以间接的使用socket来与服务器通讯。


<think>好的,我现在需要处理用户关于Java中Socket相关的面试题的查询。首先,用户提供了几个引用链接,我需要先理解这些引用的内容,看看哪些和Socket编程相关,然后根据这些内容来生成问题和答案。 引用[1]提到了线程与进程的区别,但用户的问题是关于Socket的,可能这部分不太相关,不过线程在Socket编程中可能有涉及,比如多线程处理连接,但暂时先标记一下。引用[2]是一个Java main方法的代码片段,没有直接提到Socket,可能相关性不大。引用[3]明确提到Socket编程是网络通信的基础,并简要说明了它的作用,这个需要重点参考。引用[4]详细说明了三次握手在TCP连接建立时的作用,以及在Socket编程中客户端执行connect()时会触发三次握手,这部分内容非常重要,尤其是三次握手的过程和Socket API的关系。 接下来,用户希望得到与Java Socket相关的面试题,我需要根据这些引用内容来生成相关问题。首先,基础概念方面,可能会问到Socket是什么,它在Java中的应用,TCP和UDP的区别等。然后三次握手和四次挥手是TCP的重要知识点,需要结合引用[4]中的内容来提问。Socket API的使用方法,如如何创建客户端和服务器端的Socket,以及多线程处理连接的问题,可能涉及引用[3]中的内容。异常处理和资源管理也是常见的面试题,比如端口占用或连接超时的处理。最后,实际应用场景和示例代码的编写可能会被问到,需要给出简单的代码示例。 现在需要确保每个问题都能覆盖到用户提供的引用内容,尤其是引用[3]和[4]。例如,三次握手的问题需要明确提到在Socket编程中哪个方法触发三次握手,即connect()方法。此外,代码示例部分需要符合用户提供的格式,使用正确的语法,并单独成段。 检查是否有遗漏的重要点,比如TCP与UDP的区别,Socket的生命周期,或者非阻塞IO相关的问题,但根据引用内容,可能主要集中在三次握手和基础API的使用上。需要确保生成的问题全面且符合常见的面试题类型,同时引用正确的来源,比如在三次握手的部分引用[4]。 最后,整理问题列表,确保问题结构清晰,覆盖基础、原理、API、异常处理、应用场景等方面,每个问题都能引导出关键知识点,并正确标注引用来源。</think>### Java Socket 编程面试题解答 #### 1. **什么是 Socket?它在 Java 网络编程中的作用是什么?** Socket 是网络通信的端点,用于实现不同设备间的数据传输。在 Java 中,通过 $java.net.Socket$ 和 $java.net.ServerSocket$ 类实现 TCP 协议通信,而 $java.net.DatagramSocket$ 用于 UDP 协议。Socket 编程使得应用程序能够通过 IP 地址和端口号与其他设备建立连接并交换数据[^3]。 #### 2. **TCP 三次握手在 Socket 编程中如何体现?** 三次握手是建立 TCP 连接的核心过程: 1. 客户端发送 SYN 包(同步序列号)到服务器。 2. 服务器返回 SYN-ACK 包(确认客户端的 SYN)。 3. 客户端发送 ACK 包确认服务器的 SYN。 在 Java Socket 编程中,客户端调用 $socket.connect()$ 时会触发三次握手,而服务器通过 $serverSocket.accept()$ 等待连接[^4]。 #### 3. **Java 中如何创建 TCP 客户端和服务端?** **服务端示例:** ```java try (ServerSocket serverSocket = new ServerSocket(8080)) { Socket clientSocket = serverSocket.accept(); // 等待客户端连接 // 处理输入输出流 } catch (IOException e) { e.printStackTrace(); } ``` **客户端示例:** ```java try (Socket socket = new Socket("localhost", 8080)) { // 处理输入输出流 } catch (IOException e) { e.printStackTrace(); } ``` #### 4. **TCP 和 UDP 的 Socket 编程有什么区别?** - **TCP**:面向连接,可靠传输,使用 $Socket$ 和 $ServerSocket$。 - **UDP**:无连接,不可靠但高效,使用 $DatagramSocket$ 和 $DatagramPacket$。 例如,UDP 发送数据的代码片段: ```java DatagramSocket socket = new DatagramSocket(); byte[] buffer = "数据".getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 8080); socket.send(packet); ``` #### 5. **如何处理 Socket 编程中的异常和资源泄漏?** - 使用 `try-with-resources` 自动关闭资源(Java 7+ 支持)。 - 捕获并处理 $IOException$,例如连接超时或端口占用: ```java try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress("localhost", 8080), 5000); // 超时5秒 } catch (SocketTimeoutException e) { System.out.println("连接超时"); } catch (IOException e) { e.printStackTrace(); } ``` #### 6. **多线程在 Socket 服务端中的应用场景是什么?** 服务端通常使用多线程处理多个客户端请求,避免阻塞主线程: ```java while (true) { Socket clientSocket = serverSocket.accept(); new Thread(() -> { try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) { String request = in.readLine(); // 处理请求 } catch (IOException e) { e.printStackTrace(); } }).start(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值