这里主要是想说PrintWriter的write方法和println的区别 我被坑了2小时
一开始使用的是write和flush方法 我看了看源码 write方法是不会刷新缓存的 使用flush方法 即可刷新缓存 但是此种组合在服务端像输出流写是没有问题的
但是如果在客户端 使用write和flush的组合 居然不起作用 效果就是客户端和服务器都在读取那里阻塞 还没找到原因 所以在客户端改为了println方法
其实println方法 就是调用了print和println两个方法 最终调用了newline方法 输出行标示符 和刷新缓存
private void newLine() {
try {
synchronized (lock) {
ensureOpen();
out.write(lineSeparator);
if (autoFlush)
out.flush();
}
}
看到这 那么手动输出换行是不是也是可以啊 所以可以使用
writer.write(str);
writer.write("\n");
write.flush(); 和 writer.println(str); 方法是等效的
服务端
package com.undergrowth.reactor;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class SocketServerUnder implements Runnable{
private ServerSocket serverSocket;
public SocketServerUnder(SocketAddress address) throws IOException{
serverSocket=new ServerSocket();
serverSocket.bind(address);
}
public Socket getSocket() throws IOException
{
System.out.println("等待客户端连接");
return serverSocket.accept();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Socket socket=getSocket();
System.out.println("客户端已连接");
//System.out.println(socket.getLocalAddress().getHostAddress()+"\t"+socket.getLocalPort());
new SocketServerHandler(socket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
服务端处理
package com.undergrowth.reactor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketServerHandler extends Thread {
private Socket socket;
public SocketServerHandler(Socket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
this.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
dealInputStream(socket);
dealOutputStream(socket);
close(socket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 会写给客户端的信息
*
* @param socket2
* @throws IOException
*/
private void dealOutputStream(Socket socket2) throws IOException {
// TODO Auto-generated method stub
System.out.println("处理服务器端回写客户端的消息");
OutputStream osOutputStream = socket2.getOutputStream();
if (osOutputStream != null) {
PrintWriter writer = new PrintWriter(osOutputStream, true);
// 如果使用write方法 需要调用flush方法 但是有时不起作用 客户端和服务器端还是无法接受到消息的内容
// 还是使用println
writer.println("服务器已收到客户端信息");
writer.flush();
} else {
throw new IOException("获取服务端的输出流为空");
}
}
private void dealInputStream(Socket socket) throws IOException {
System.out.println("处理服务器端读取客户端的消息");
InputStream inputStream = socket.getInputStream();
// System.out.println(inputStream);
if (inputStream != null) {
// 读完客户端发送的数据 将数据会写给客户端
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
String s;
// while(true)
{
s = reader.readLine();
// if(s!=null&&s.equals("结束")) break;
// if(s!=null) System.out.println(s);
System.out.println(s);
}
System.out.println("结束服务器端读取客户端信息");
} else {
throw new IOException("获取服务端的输入流为空");
}
}
private void close(Socket socket) throws IOException {
if (!socket.isClosed()) {
System.out.println("处理客户端关闭服务端的连接");
if (!socket.isClosed() && !socket.isInputShutdown())
socket.getInputStream().close();
if (!socket.isClosed() && !socket.isOutputShutdown())
socket.getOutputStream().close();
if (!socket.isClosed())
socket.close();
}
}
}
客户端
package com.undergrowth.reactor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class SocketClientUnder {
private Socket socket;
public Socket getSocket() {
return socket;
}
public SocketClientUnder(String ip,int port) throws IOException{
socket=new Socket(InetAddress.getLocalHost(), 6666);
}
public InputStream getInputStream() throws IOException{
return socket.getInputStream();
}
public OutputStream getOutputStream() throws IOException{
return socket.getOutputStream();
}
public void write(String str) throws IOException{
System.out.println("处理客户端回写服务端的消息");
OutputStream osOutputStream=getOutputStream();
if(osOutputStream!=null){
PrintWriter writer=new PrintWriter(osOutputStream,true);
//如果使用write方法 需要调用flush方法 但是有时不起作用 客户端和服务器端还是无法接受到消息的内容
//还是使用println
writer.println(str);
writer.flush();
System.out.println("写完客户端回写服务端的消息");
}else {
throw new IOException("获取客户端的输出流为空");
}
}
public void read() throws IOException {
System.out.println("处理客户端读取服务端的消息");
InputStream inputStream=getInputStream();
if(inputStream!=null){
//读完客户端发送的数据 将数据会写给客户端
BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream));
String s;
//while(true){
s=reader.readLine();
//if(s!=null&&s.equals("结束")) break;
//if(s!=null) System.out.println(s);
System.out.println(s);
//}
System.out.println("结束客户器端读取服务端信息");
}else {
throw new IOException("获取客户端的输入流为空");
}
}
public void close() throws IOException
{
if(!socket.isClosed()){
System.out.println("处理客户端关闭服务端的连接");
if(!socket.isClosed()&&!socket.isInputShutdown()) socket.getInputStream().close();
if(!socket.isClosed()&&!socket.isOutputShutdown()) socket.getOutputStream().close();
if(!socket.isClosed()) socket.close();
}
}
}
测试代码
package com.undergrowth.reactor;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
public class SocketTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
SocketAddress address=new InetSocketAddress(InetAddress.getLocalHost(), 6666);
SocketServerUnder serverUnder=new SocketServerUnder(address);
//服务器端等待
new Thread(serverUnder).start();
//System.out.println(InetAddress.getLocalHost().getHostAddress());
//客户端连接
SocketClientUnder socketClient=new SocketClientUnder(InetAddress.getLocalHost().getHostAddress(),6666);
//System.out.println("客户端连接");
//socketClient.getSocket().connect(address);
//System.out.println("客户端连接");
//for(int i=0;i<10;i++)
socketClient.write("来自客户端的信息");
//socketClient.write("来自客户端的信息2");
//socketClient.write("结束");
socketClient.read();
socketClient.close();
}
}