Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
服务器端的ServerSocket创建只需要指定相应的端口就可以了
ServerSocket server = new ServerSocket(port);
客户端Socket构造则需要指定IP地址和服务器的端口号
Socket socket = new Socket(ip, poet);
Socket有两个非常有用的方法,分别返回InputStream 和 OutputStream
直接对输入输出流操作并不是很好的意见,通过包装输入输出流可以得到更加直观的往socket中输入数据和接受接收到的数据
BufferdeReader in = new BufferedReader( new InputStreamReader(socket .getInputStream()));
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket .getOutputStream())), true);
读取数据时的操作
String str = null;
//只有当对方发送来的字符串为quit的时候结束连接
while(!(str = in.readLine()).equals("quit"))
{
//something method to process str
}
写数据则更加简单
out.println("some data to write");
结合其他的java知识,接下设计一个简单的具有用户界面的Client和Server
Client.java
package lzl.cxl.client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class Client {
private final String IP = "127.0.0.1";
private final int PORT = 4046;
private JFrame f;
private JTextField textField;
private JButton sendButton;
private JTextArea textArea;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Client() throws UnknownHostException, IOException
{
f = new JFrame("Client");
textField = new JTextField(20);
textArea = new JTextArea(20, 10);
sendButton = new JButton("Send");
init();
}
private void init()
{
f.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.add(textField);
panel.add(sendButton);
f.add(panel, "North");
f.add(textArea, "Center");
f.setSize(400, 300);
f.setVisible(true);
}
public void connect() throws UnknownHostException, IOException
{
socket = new Socket(IP, PORT);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
sendButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
textArea.append(getSystemTime() + " " + textField.getText() + "\n");
out.println(textField.getText());
textField.setText("");
}
});
new Thread(){
public void run(){
String str = null;
while(true) {
try {
if ((str = in.readLine()).equals("bye")){
socket.close();
f.dispose();
break;
}
else
textArea.append(getSystemTime() + " " + str + "\n");
Thread.sleep(200);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public String getSystemTime()
{
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
public static void main(String[] args) throws UnknownHostException, IOException
{
Client c = new Client();
c.connect();
}
}
Server.java
import java.io.*;
import java.net.*;
public class Server {
private static final int PORT = 4046;
public static void main(String [] args) throws IOException
{
ServerSocket server = new ServerSocket( PORT);
System. out .print("Server have started" );
Socket socket = server .accept();
System. out .println("Accepted client: " + socket);
try {
BufferedReader in = new BufferedReader( new InputStreamReader(
socket .getInputStream()));
PrintWriter out = new PrintWriter( new BufferedWriter(
new OutputStreamWriter(socket .getOutputStream())), true);
while (true ) {
String str = in .readLine();
if (str .equals( "quit")) {
out .println("bye" );
break ;
}
System. out .println("Reveived info: " + str);
out .println("OK" );
}
} finally {
System. out .println("Finished" );
socket .close();
server .close();
}
}
}
就这样先运行Server.java再运行Client.java。大致的效果就是这样的
可以在文本框中输入,点击send就会发送给Server,Server会返回OK,同时textArea区域会更新收到和发送的数据。发送quit则会终止连接。