使用jdk的socket通信

使用JDK提供的API进行网络通信,会用到Socket,ServerSocket两个类。写个简单的SERVER和CLIENT之间发消息的小程序,竟然发现了挺多的问题。

这是服务器端代码:

 

package org.chat;



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 ChatServer {



	public static void main(String[] args) {

		ChatServer server = new ChatServer();

		server.start();

	}



	public void start() {

		while (true) {

			ServerSocket s = null;

			Socket socket = null;

			try {

				s = new ServerSocket(10001);

				socket = s.accept();

				

				BufferedReader 	in 	= new BufferedReader(new InputStreamReader(socket.getInputStream()));

				PrintWriter 	out = new PrintWriter(socket.getOutputStream(),true);

	

				String content = in.readLine();

				System.out.println(content);

				content = content + "1";

				out.print(content);

				out.flush(); // if not flush, client can't receive data

				

				in.close();

				out.close();

				

			} catch (IOException e) {

				e.printStackTrace();

			} finally{

				try {

					s.close();

					socket.close();

				} catch (IOException e) {

					e.printStackTrace();

				}

			}

		}

	}

}


这是客户端代码:

 

 

package org.chat;



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 Client {

	public static void main(String[] args) {

		Socket socket = null;

		try {

			socket = new Socket("128.192.184.93", 10001);

			

			BufferedReader 	in 	= new BufferedReader(new InputStreamReader(socket.getInputStream()));

			PrintWriter 	out = new PrintWriter(socket.getOutputStream(), true);

			

			out.println("hello");

			

			String reply = in.readLine();

			System.out.println(reply);

			

			in.close();

			out.close();

			

		} catch (UnknownHostException e) {

			e.printStackTrace();

		} catch (IOException e) {

			e.printStackTrace();

		} finally{

			try {

				socket.close();

			} catch (IOException e) {

				e.printStackTrace();

			}

		}

	}

}

 

逻辑很简单:Client会向ChatServer发一个字符串"hello",ChatServer收到后,在这个字符串后面加1,然后发给Client。

这其中遇到了几个问题:

1.PrintWriter构造函数参数autoFlush设置

PrintWriter的构造函数里的第二个参数autoFlush,API文档里解释是:if true, the println,printf, or format methods will flush the output buffer。注意不包括print。

因此,对于ChatServer,32,33行(print),如果不调用flush,Client就收不到数据,尽管在PrintWriter的构造函数里,autoFlush=true;而Client的19行(println),无需调用flush,也能发送数据。

2.Socket的InputStream和OutputStream有关联,如果一个在用,另一个不可关闭

在ChatServer中,如果把35行代码in.close()放到29行之后,30行之前,也就是说,in在读取了数据之后,就关闭掉,造成的后果就是32行代码out.print()失效,这是因为in.close()使socket关闭了,Client只能收到一个null

3.BufferReader的readLine()方法

首先,改方法是阻塞的,如果读不到(即使读到null也算读到),就会阻塞。

该方法会读取一行数据,就是说,读取第一个换行符之前的数据,如果发送的数据中没有换行符,那么,readLine可能会阻塞。

PrintWriter.print()发送的数据中没有换行符,所以多次调用,接受方BufferReader.readLine()读到的数据包括了多次print的数据。


 

 

你可能感兴趣的:(socket通信)