java中Socket类可以进行一些服务器与客户机通信之类的工作,这一点虽然并不算很是高明,对于一个学习java的新手,能够灵活使用Socket类编写出简单的网络聊天程序,这一点是必须达到的能力要求!Socket一共有两个类比较重要:一类是用于服务器端的ServerSocket类,另外一类是客户端的Socket类。
Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上数据的传递。在Java中,有专门的Socket类来处理用户的请求和响应。利用Socket类的方法,就可以实现两台计算机之间的通讯。这里就介绍一下在Java中如何利用Socket进行网络编程。
一、建立服务器类
Java中有一个专门用来建立Socket服务器的类,名叫ServerSocket,可以用服务器需要使用的端口号作为参数来创建服务器对象。
ServerSocket server = new ServerSocket(10000) |
这条语句创建了一个服务器对象,这个服务器使用10000号端口。当一个客户端程序建立一个Socket连接,所连接的端口号为9998时,服务器对象server便响应这个连接,并且server.accept()方法会创建一个Socket对象。服务器端便可以利用这个Socket对象与客户进行通讯。
Socket incoming = server.accept() |
进而得到输入流和输出流,并进行封装
BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter(incoming.getOutputStream(),true); |
随后,就可以使用in.readLine()方法得到客户端的输入,也可以使用out.println()方法向客户端发送数据。从而可以根据程序的需要对客户端的不同请求进行回应。
在所有通讯结束以后应该关闭这两个数据流,关闭的顺序是先关闭输出流,再关闭输入流,即使用
out.close(); in.close(); |
二、建立客户端代码
相比服务器端,客户端要简单一些,客户端只需用服务器所在机器的ip以及服务器的端口作为参数创建一个Socket对象。得到这个对象后,就可以用"建立服务器"部分介绍的方法实现数据的输入和输出。
Socket socket = new Socket("127.0.0.1",10000); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); |
以上的程序代码建立了一个Socket对象,这个对象连接到ip地址为127.0.0.1(默认地址)的主机上、端口为10000的服务器对象。并且建立了输入流和输出流,分别对应服务器的输出和客户端的写入。
三、建立用户界面
读者可以根据自己的喜好建立自己的用户界面,这不是本文的重点。
经过以上三个步骤,就可以建立一个比较简单的对话程序。下面是我写的一个程序:有心的朋友可以自己运行一下
package rick_demo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Test extends JFrame{
/**@author Rick
* the class is about how to communicate by socket ,the UI is
* friendly with swing ,and Multi-threading technology is
* useful when you want to the program respond you in time
* and this <code>Test</code> is use as client
*/
private static final long serialVersionUID = 1L;
private Pane pan;
private Container c= new Container();
public Test(){
this.setSize(200, 200);
pan = new Pane();
c=this.getContentPane();
c.add(pan);
c.setBackground(Color.black);
c.setForeground(Color.white);
c.setVisible(true);
this.setVisible(true);
}
public static void main(String[] args){
SocketDemo sd= new SocketDemo();
sd.setDaemon(true); //将服务器线程设为后台线程
sd.start(); //要比客户机程序先启动服务器程序
new Test();
}
}
class Pane extends JPanel{
/**
*
*/
private static final long serialVersionUID = 5089011654522261240L;
private Socket ss ;
private JTextArea ta= new JTextArea(20,10);
private JScrollPane jp = new JScrollPane(ta);
private static JTextField tf= new JTextField(15);
private PrintWriter out ;
private BufferedReader in;
private static String str=new String(); //获得输入框的文字
private String date = new String();
private SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault()) ;
private JPanel demo= new JPanel();
private JButton btn = new JButton("发送");
public Pane(){
this.setSize(new Dimension(200,200));
this.setLayout(new BorderLayout());
add(jp,BorderLayout.CENTER);
demo.setSize(new Dimension(200,10));
demo.add(tf);
demo.add(btn);
add(demo,BorderLayout.SOUTH);
df.setTimeZone(TimeZone.getTimeZone("GMT+8"));//reset the time zone
this.setVisible(true);
btn.addActionListener(new JianTing());
btn.addKeyListener(new JianTing());
tf.addKeyListener(new JianTing());
ta.addKeyListener(new JianTing());
}
public static String getString(){
str = tf.getText();
return str;
}
private class JianTing implements ActionListener,KeyListener {
public void actionPerformed(ActionEvent e){
if(e.getSource()==btn){
str= Pane.getString();
date= df.format(Calendar.getInstance().getTime());
ta.append(date+"\n 客户机:"+str+"\n");
try {
ss= new Socket("127.0.0.1",10000);
out = new PrintWriter(ss.getOutputStream(),true);
out.println(str);
in = new BufferedReader
(new InputStreamReader(ss.getInputStream()));
ta.append(date+"\n 服务器:"+in.readLine()+"\n");
System.out.println("服务器说:"+in.readLine());
in.close();
out.close();
ss.close();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e){ //和actionPerformed方法内容完全一样!
if(e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("hello ");
str= Pane.getString();
date= df.format(Calendar.getInstance().getTime());
ta.append(date+"\n 客户机:"+str+"\n");
try {
ss= new Socket("127.0.0.1",10000);
out = new PrintWriter(ss.getOutputStream(),true);
out.println(str);
in = new BufferedReader
(new InputStreamReader(ss.getInputStream()));
ta.append(date+"\n 服务器:"+in.readLine()+"\n");
System.out.println("服务器说:"+in.readLine());
in.close();
out.close();
ss.close();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){
}
}
}
/**
* 服务器类只负责接受信息和发送信息,不做其他事
*/
class SocketDemo extends Thread{
private ServerSocket ss ;
private Socket s1;
private PrintWriter out1;
//private BufferedReader tempOut;
private BufferedReader in1;
public void run(){
while(true){
try{
ss= new ServerSocket(10000);
s1=ss.accept();
System.out.println("successfully connect the server now ");
/*send the data to the client machine */
//tempOut = new BufferedReader(new InputStreamReader(s1.getInputStream()));
out1 = new PrintWriter(s1.getOutputStream(),true);
out1 .println("已经收到你的信息");
/*receive the data from client machine*/
in1= new BufferedReader(new InputStreamReader(s1.getInputStream()));
System.out.println(in1.readLine());
in1.close();
out1.close();
//tempOut.close();
ss.close();
}catch(IOException e){
}
}
}
}