用java,搞通信一定会接触到Socket,ServerSocket这2个类,基本使用非常简单,但如果想良好的控制,还是得小心之非常啊.因为Socket中InputStream的read()当管道无数据时便等待数据的填充,但OutputStream可以继续写入数据.如果这点搞清楚了,就没多大的问题了,
read()阻塞后,继续想服务器提交数据,read()方法便会读出服务器的响应数据来.
此次便是记录下,如何比较随心的使用java的Socket.
2个类,
TCPClient:
启动TCPServer,之后运行TCPClicent,在小窗口中输入字符,bye退出.
read()阻塞后,继续想服务器提交数据,read()方法便会读出服务器的响应数据来.
此次便是记录下,如何比较随心的使用java的Socket.
2个类,
TCPServer
package org.sk.lib.socket;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TCPServer {
private ServerSocket server;
private Socket client;
public TCPServer(int port) throws IOException {
// TODO Auto-generated constructor stub
server = new ServerSocket(port);
}
/**
* 开始tcp的服务
* @throws IOException
*/
public void start() throws IOException{
while(true){
client = server.accept();
new Thread(new ClientThread(client)).start();
}
}
public static void main(String[] args) throws IOException {
new TCPServer(1234).start();
}
/**
* 客户端处理
* @author Ozone
*
*/
class ClientThread implements Runnable{
private Socket client;
private Scanner in;
private PrintStream out;
public ClientThread(Socket client) throws IOException {
// TODO Auto-generated constructor stub
this.client = client;
in = new Scanner(client.getInputStream());
out = new PrintStream(client.getOutputStream());
}
public void run() {
// TODO Auto-generated method stub
try {
blockProcess();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/***
* 处理客户端的请求,一条一条的进行处理,每次接收1行指令,指令以\n为结束
* @throws IOException
*/
private void blockProcess() throws IOException{
String line;
while(in.hasNextLine()){
line = in.nextLine();
if(line.equals("bye")){
out.println("bye");
break;
}
{
//需要进行处理
System.out.println(line);
out.println("a\nb\nc\nd");
}
}
in.close();
out.close();
client.close();
}
}
}
TCPClient:
package org.sk.lib.socket;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class TCPClient {
private Socket client;
private PrintWriter out;
private Scanner in;
public TCPClient(String addr, int port) throws UnknownHostException,
IOException {
client = new Socket(addr, port);
in = new Scanner(client.getInputStream());
out = new PrintWriter(client.getOutputStream(),true);
}
//初始化 一个窗体
public void initFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
final JTextArea ta = new JTextArea();
frame.add(ta, BorderLayout.NORTH);
JButton bt = new JButton("go");
frame.add(bt, BorderLayout.CENTER);
frame.pack();
bt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(!ta.getText().equals(""))
send(ta.getText());
}
});
}
/**
* 将数据发送至 输出流
* @param cont
*/
private void send(String cont){
out.println(cont);
}
/***
* 处理客户端的读取操作
* 1 当管道内无数据(服务器无响应)便阻塞.
* 2 管道内有多行数据,便一直读取到完,
* 1,2 循环,直到收到服务器的bye字符,连接关闭,会话结束
* @throws IOException
*/
public void registerListener() throws IOException {
String line;
while (in.hasNextLine()) {
line = in.nextLine();
if(line.equals("bye")){
break;
}
//处理服务器响应
System.out.println(line);
}
in.close();
out.close();
client.close();
System.out.println("连接关闭");
}
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
TCPClient client = new TCPClient("127.0.0.1",1234);
client.initFrame();
client.registerListener();
}
}
启动TCPServer,之后运行TCPClicent,在小窗口中输入字符,bye退出.