初步尝试了解下socket编程,结果被一个问题困扰了一天,回想真是失败~总结原因
1 明显的java功底太弱,对各种类的了解不彻底深入
2 解决问题的方法不够理性,系统~
陈述问题,最简单的情况,单线程交互,问题代码如下:
server:
package sl.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class BugServer {
public static void main(String[] args) {
ServerSocket ss = null;
try {
ss = new ServerSocket(10000);
System.out.println("server start...");
while(true){
Socket socket = ss.accept();
System.out.println("a client come in :"+socket.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//注意:if true, the println, printf, or format methods will flush the output buffer
//即使autoflush了,也只对三个方法有效!
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
//若客户段没有使用autoflush方法,服务段将阻塞在这一行
System.out.println(in.readLine());
//问题出在这里,调用的不是autoflush的方法,即使后面有 pw.flush() 也不行!
pw.println("服务端反馈! to "+ socket.toString());
pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
client:
package sl.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class BugClient {
Socket soc;
public static void main(String[] args){
new BugClient().send();
}
private void send() {
try {
soc = new Socket("127.0.0.1",10000);
PrintWriter socOut = new PrintWriter(soc.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedReader netIn = new BufferedReader(new InputStreamReader(soc.getInputStream()));
String line = in.readLine();
System.out.println("input: "+line);
// 若使用了非 autoflush方式,即使显示flush的话,更是连服务端都收不到消息!
//由于消息没有"立即"传输到服务端, 会使得server在 阻塞在 in.readline()那一行.
socOut.print(line);
socOut.flush();
//若将此行注释掉,即客户段放弃接收服务段消息,
//那么这个客户段程序可以跑完,服务端将接收到消息,造成 socOut.flush()好像立即起了作用的假像
//实际上,并不是 flush()那行代码起了作用,而是程序结束时,对 out流做清理工作,使得消息最终发送了过去
/**
* 启用一下两行代码,由于 服务段已经被阻塞了,更别说响应,则客户段将阻塞在 netIn.readline();
*/
System.out.println(netIn.readLine());
soc.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
就这样一个问题困扰了我一天,虽然最终发现了问题所在,也可以解决问题,但是理解上还没有透彻。
依然的困惑:
1 流的传输中flush的机制到底是怎样的,为什么显示的调用flush()都没有效果,又为什么放弃了客户段接收信息,程序结束时,消息最终还是传向了服务端?
2 socket的内部机制,在javaeye看帖时看到一句话,算是识记了这个知识,但不理解
“
Socket的发送与接收是需要同步进行的,即客户端发送一条信息,服务器必需先接收这条信息, 而后才可以向客户端发送信息,否则将会有运行时出错。 ”
感叹一些自己的java如此单薄~
[size=medium]今天又看了一些资料,发现以上理解全部错了~ 阻塞的真正原因是因为 readline()一直在寻找 换行符号"\n",而根本就不是flush的原因![/size]
分享到:
相关推荐
下面是一个简单的Java Socket客户端示例,用于连接到一个聊天服务器: ```java import java.io.*; import java.net.*; public class ChatClient { public static void main(String[] args) { try (Socket socket...
通过创建Socket实例,客户端可以连接到服务器的特定端口,建立起通信链路。 2. **Java ServerSocket类**: - ServerSocket类用于监听客户端的连接请求。服务器端通过创建ServerSocket并指定一个端口号,进入监听...
标题:HP用SOCKET实现(客户端---服务端) 描述:HP用SOCKET实现(客户端---服务端)通信 本文将深入解析如何利用PHP中的Socket编程技术实现客户端与服务端之间的通信,通过分析提供的代码示例,我们将理解其工作原理、...
在IT领域,网络通信是不可或缺的一部分,而Java Socket编程则是实现网络通信的一种常见方式,尤其在TCP/IP协议栈上。本教程将详细讲解如何利用Java Socket实现基于TCP/IP的服务端和客户端之间的报文发送与接收。 ...
本篇文章将详细讲解如何使用Java实现UDP协议的Socket客户端和服务器程序。 首先,UDP是一种无连接的、不可靠的传输层协议,它不像TCP那样建立和维护连接,而是直接发送数据报文,每个数据报文独立处理,没有顺序...
Java Socket邮件客户端是一种基于Java编程语言,利用Socket通信协议实现的邮件收发工具。它能够帮助开发者通过编程接口与邮件服务器进行交互,实现发送、接收邮件的功能。在本项目中,"LaserMail.2.03BLOOD"可能是这...
客户端使用`Socket`类创建连接到服务器的实例,而服务器端则使用`ServerSocket`类监听传入的连接请求。 1. **服务器端实现:** - 创建`ServerSocket`实例,指定一个端口号来监听客户端的连接。例如: ```java ...
Java基于socket实现的客户端和服务端通信功能完整实例 在Java中,Socket是实现网络通信的基础,通过Socket可以实现客户端和服务器端之间的通信。本文将详细介绍Java基于Socket实现的客户端和服务端通信功能,包括...
在Java中,`Socket`类用于创建客户端套接字,`connect()`方法用于连接到指定的服务器地址和端口。一旦连接建立,客户端也可以通过Socket实例进行数据传输。 描述中提到的“优化了数据传输的中文问题”,这可能指的...
Echo服务器是一种简单的网络服务,它接收到客户端发送的数据后,原样返回。在Java中,我们可以使用`ServerSocket`类创建服务器端的套接字,并监听特定端口。当有客户端连接时,`accept()`方法会被阻塞,直到一个新的...
在这个场景中,我们将讨论如何使用Java实现一个简单的文件传输功能,即客户端通过Socket连接将文件发送到服务器。 首先,我们需要理解Socket通信的基本流程: 1. **服务器端**: - 创建`ServerSocket`实例,指定...
服务器端通常会使用ServerSocket监听特定端口,接收到客户端请求后创建Socket连接,并通过Socket的InputStream读取客户端发送的数据,然后通过OutputStream回传响应。服务器端的实现不在本文讨论范围内,但它是整个...
### 基于Java Socket网络编程的关键知识点 #### 一、网络基础——TCP/IP协议 TCP/IP(Transmission Control Protocol/Internet Protocol)协议是互联网最基本的协议之一,它定义了电子设备如何连接到因特网以及...
Java客户端Socket与Mina服务端通信是网络编程中常见的应用场景,尤其在开发分布式系统或实时数据传输时。这里我们将深入探讨这两个技术,并了解如何通过它们建立保持长连接的通信。 首先,Socket是Java中用于实现...
本教程主要探讨的是如何在Java中使用Socket实现多线程阻塞式通信,这通常涉及到服务器端(EchoServer)和客户端(EchoClient)的设计。在本文中,我们将详细解析`EchoServer.java`、`SocketUtils.java`和`EchoClient...
Java Socket聊天程序是一种基于Java语言实现的局域网内通信工具,主要利用Socket类进行网络数据传输,实现客户端与服务器端的实时交互。这个简单的聊天程序仅支持文字发送,不包含图片、音频或其他多媒体文件的传输...
在Java中,Socket通常被用来实现客户端-服务器架构,其中服务器监听特定端口上的连接请求,而客户端则向该端口发送连接请求。下面我们将详细探讨Java Socket在客户端和服务端的应用。 首先,我们来看服务端的实现。...
在"echo"部分,服务器端接收到客户端的消息后,不做任何处理,直接将接收到的数据通过`Socket`的`OutputStream`回送给客户端,这就是所谓的回显服务。客户端收到服务器的回应后,通常会在控制台显示出来,完成一次...
当接收到新客户端的数据时,将数据和客户端的IP地址/端口号关联存储,然后在广播消息时,遍历这个列表,向每个客户端发送数据。 6. 实现细节 - 错误处理:需要考虑UDP数据包丢失、重复或乱序的情况,以及处理可能...
在Android开发中,网络编程是不可...总之,Android中的Java Socket客户端是通过建立连接、获取输入/输出流、发送和接收数据以及关闭连接来实现的。理解和掌握这些基础知识对于开发涉及网络通信的Android应用至关重要。