java中网络通讯主要是通过两个类来实现,一个是服务器(ServerSocket),另一个是客户端(Socket)。
首先,实现一个简单的服务器程序:
public class ChatServer { /** * 在指定端口上启动一个服务器 */ public void setUpServer(int port){ try{ //建立绑定在指定端口上的服务器对象 ServerSocket server=new ServerSocket(port); System.out.println("服务器创建成功!"+port); while(true){ //让服务器进入等待状态:阻塞状态 Socket client=server.accept(); //从连接对象上得到输入输出流对象 OutputStream out=client.getOutputStream(); InputStream ins=client.getInputStream(); String s="你好,欢迎来javake.com\r\n"; byte[] data=s.getBytes(); out.write(data); out.flush(); int in=0; while(in!=13){ in=ins.read(); char ch=(char)in; System.out.println("读到的是:"+ch); } System.out.println("得到回车,退出!"); client.close(); } }catch(Exception ef){ ef.printStackTrace(); } } //主函数 public static void main(String[] args){ ChatServer cs=new ChatServer(); cs.setUpServer(9090); } }
然后用windows提供的telnet客户端去连接测试;服务器有IP和端口号,端口号的范围一般在0到65535之间。服务器有输出流
和输入流,输出流是输出信息到客户端的,输入流是接受客户端发来的信息的,我们通过相应的方法去处理接受的数据,同时
可以通过线程去解决信息阻塞的问题,实现发送消息的同时接受消息。
也可以用过各种途径实现网络五子棋,网络画板等网络程序。
客户端,跟服务器差不多,区别就是多个客户端可以同时连接一个服务器,然后客户端直接可以通讯。具体实现看代码。
package Client_v1; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextArea; public class ClientThread extends Thread { private Socket client; private OutputStream ous; private InputStream ins; public ClientThread(Socket client){ this.client=client; } //界面组件 private JFrame frame=new JFrame("客户端"); private JTextArea Rjta=new JTextArea(8,25); private JTextArea Sjta=new JTextArea(4,25); private JButton sbt=new JButton("发送"); /** * 显示界面 * @return */ public void showUI(){ frame.setSize(300,400); frame.setTitle("客户端"); frame.setDefaultCloseOperation(3); frame.setLayout(new FlowLayout()); frame.add(Rjta); frame.add(Sjta); frame.add(sbt); frame.setVisible(true); sbt.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { SendMassager(Sjta.getText()); Sjta.setText(""); } }); } /** * run方法 */ public void run(){ showUI(); processMsg(client); } /** * 处理消息的函数 */ public void processMsg(Socket client){ client=this.client; try { ins=client.getInputStream(); while(true){ //Rjta.setText("服务器:"+readString(ins)); Rjta.append(readString(ins)+"\r\n"); System.out.println("1"); } //client.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 发送消息的方法 * @throws IOException */ public void SendMassager(String std) { std=std+"\r\n"; byte data[]=std.getBytes(); try { ous=client.getOutputStream(); ous.write(data); ous.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 收到的字符换成字符串 * @throws IOException */ public String readString(InputStream ins) throws IOException{ StringBuffer std=new StringBuffer(); char ch=0; int in=0; while(ch!='\n'){ in=ins.read(); ch=(char)in; std.append(ch); } System.out.println("xxx:"+std.toString()); return std.toString().trim();//trim为消除后面的空格符 } public static void main(String[] args){ Socket soc; try { soc = new Socket("localhost",9090); ClientThread cl=new ClientThread(soc); cl.start(); } catch (IOException e) { e.printStackTrace(); } } }
难点在于如何用线程去实现发收信息的同步。