Java_Socket简单通信

这里主要是想说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();
	}

}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值