发现一个问题
Socket编程中要慎用
PrintStream和PrintWriter,首先创建时要注意加上 true,自动flush,否则数据无法发送出去,
其次它们的println()要用它们的readLine来读取,如果你用用DataInputStream.readUTF读取将导致阻塞,一直都读取不到数据,见下面代码就是。
package com.chat.server.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
InputStream is = null;
DataInputStream dis = null;
OutputStream os = null;
// DataOutputStream dos = null;
PrintStream pos = null;
ServerSocket ss = new ServerSocket(10001);
try
{
while(true)
{
Socket soc = ss.accept();
is = soc.getInputStream();
dis = new DataInputStream(is);
os = soc.getOutputStream();
// dos = new DataOutputStream(os);
pos = new PrintStream(os,true);
try
{
InetAddress clientAddr = soc.getInetAddress();
String str = "欢迎客户" + clientAddr + "到访,该客户占用端口"
+ soc.getPort() ;
pos.print(str+"\r\n\n");
//pos.flush();
//dos.writeUTF(str);
// dos.flush();
str = dis.readUTF();
while (!"quit".equals(str))
{
System.out.println("client said:" + str);
str = dis.readUTF();
}
System.out.println(clientAddr + " leave");
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
is.close();
os.close();
soc.close();
}
}
}
finally
{
if(ss != null){
ss.close();
}
}
}
}
package com.chat.server.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class Client
{
public static void initArray(byte[] arr)
{
Arrays.fill(arr, (byte)0);
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
InputStream is = null;
DataInputStream dis = null;
OutputStream os = null;
DataOutputStream dos = null;
Socket soc = new Socket();
InetAddress address = InetAddress.getLocalHost();
InetSocketAddress endpoint = new InetSocketAddress(address,10001);
soc.connect(endpoint);
byte bmsg[] = new byte[1024];
initArray(bmsg);
String msg = null;
try
{
is = soc.getInputStream();
dis = new DataInputStream(is);
os = soc.getOutputStream();
dos = new DataOutputStream(os);
String str = dis.readLine();
//String str = dis.readUTF();
System.out.println("Server said:"+ str);
int num = System.in.read(bmsg);
msg = new String(bmsg,0,num);
msg = msg.substring(0,msg.length() -2);
while(!"quit".equals(msg))
{
dos.writeUTF(msg);
dos.flush();
num = System.in.read(bmsg);
msg = new String(bmsg,0,num);
msg = msg.substring(0,msg.length() -2);
}
dos.writeUTF(msg);
dos.flush();
}
finally
{
if(soc != null)
{
soc.close();
}
}
}
}
如果Client中的dis.readLine改成dis.readUTF,则会在dis.readUTF一直阻塞。
分享到:
相关推荐
java 输出流中的PrintStream 和 PrintWriter有什么区别
如果PrintStream被设置为autoFlush,那么它会在写入字符串时自动执行flush方法,而PrintWriter则不同,它会在调用println、printf、format方法时自动执行flush方法。 此外,PrintStream和PrintWriter在换行符方面也...
PrintStream和PrintWriter都是Java中的输出流类,都是用于将数据输出到目标设备的类,但是它们之间存在一些关键的区别。 首先,从构造方法上看,PrintStream和PrintWriter的构造方法非常相似,都是可以输出各种形式...
在某些特定的编程环境中,使用PrintWriter会比较方便,而PrintStream无法替代的作用。 在Java I/O流中,PrintStream和PrintWriter都是非常重要的组件,它们可以帮助开发者快速地输出数据。了解PrintStream和...
Java中的Socket类是进行网络通信的核心组件,它主要用于实现客户端与服务器之间的TCP连接,从而进行双向数据传输。本文将深入探讨如何使用Socket类接收和发送数据。 首先,我们需要理解Socket类的基本概念。Socket...
在Java编程语言中,`PrintStream`, `StringBuilder` 和 `Formatter` 是三个非常重要的类,分别用于不同的输出处理。理解并熟练使用这三个类是提升Java编程能力的关键。 首先,我们来详细了解一下`PrintStream`。它...
接着,通过Socket对象获取输入流和输出流,通常是InputStream、OutputStream以及DataInputStream和PrintStream,用于读写数据。服务器端会持续接收客户端发送的信息,直到接收到"BYE"为止。 客户端程序则需要创建一...
- 从接收到的DatagramPacket中获取数据和发送者的地址信息。 - 通过DatagramSocket的send()方法向特定地址发送数据。 2. **客户端:** - 创建DatagramSocket,用于发送和接收数据。 - 构造DatagramPacket,包含...
- 然后,通过Socket的`getOutputStream()`获取输出流,用于向服务器发送数据,`getInputStream()`获取输入流,用于接收服务器的数据。 - 发送数据可以使用`DataOutputStream`或`PrintStream`,例如: ```java ...
Java和C++之间的Socket通信是跨语言网络编程的一个常见应用场景,尤其在系统集成、设备通讯或者混合编程中。Socket提供了一种基于TCP/IP协议的进程间通信(IPC)方式,可以实现在不同操作系统上的进程之间的数据传输...
总的来说,“socket字符发送”涉及了网络通信的基础知识,包括Socket接口的使用、TCP连接的建立以及字符串在Socket中的传输方式。实际编程中,还需要考虑异常处理、多线程(尤其是服务器端处理多个并发连接时)、...
2. **数据传输**:一旦连接建立,我们可以通过`Socket`的`getOutputStream()`方法获取到输出流,然后使用`DataOutputStream`或`PrintStream`写入邮件内容。对于输入流,可以用`getInputStream()`获取,但在邮件发送...
PrintStream 是打印输出流,它继承于FilterOutputStream。...它产生的IOException会被自身的函数所捕获并设置错误标记, 用户可以通过 checkError() 返回错误标记,从而查看PrintStream内部是否产生了IOException。
可以使用`readUTFBytes`或`readUTF`读取接收到的字符串,如`var receivedData:String = socket.readUTFBytes(socket.bytesAvailable);`。 5. **错误处理**:需要监听`error`事件来捕获可能出现的连接错误。 **Java...
根据提供的文件信息,我们可以整理出以下关于Socket编程在Java中的应用和实现的相关知识点: ### Socket基础知识 - **定义**:Socket是一种通信模型,用于不同计算机系统间的网络通信。 - **功能**:它允许一个...
一旦客户端请求被接受,服务器Socket会返回一个新的Socket对象,代表与客户端的连接。这个新的Socket可以用来读取和写入数据。在给出的FTP服务器模拟程序中,`ftpserver.accept()`方法就是等待客户端的连接,`fs=ftp...
- **数据发送**:通过`Socket`对象的`getOutputStream()`方法获取到输出流,然后使用`DataOutputStream`或`PrintStream`向服务器写入数据。 - **数据接收**:通过`Socket`对象的`getInputStream()`方法获取输入流...
- **文本数据**:使用`PrintWriter`或`PrintStream`的`print()`方法来发送。 - **二进制数据**:利用`OutputStream.write(byte[])`方法发送。 - **状态码与响应头**:正确设置状态码和响应头,如`Content-Type`,以...
首先,Socket,也被称为套接字,是网络通信中的一个抽象接口,它允许两个运行在不同设备上的应用程序通过网络进行数据交换。在TCP/IP协议栈中,Socket分为两种类型:流式Socket(TCP)和数据报Socket(UDP)。在这个...