Java 网络编程
2011-12-05 19:52
190 查看
第一步 充分理解Socket
1.什么是socket
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
重要的Socket API:
java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK文档。
. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
. getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例,。
. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
2.如何开发一个Server-Client模型的程序
开发原理:
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
第二步 多个客户同时连接
在实际的网络环境里,同一时间只对一个用户服务是不可行的。一个优秀的网络服务程序除了能处理用户的输入信息,还必须能够同时响应多个客户端的连接请求。在java中,实现以上功能特点是非常容易的。
设计原理:
主程序监听一端口,等待客户接入;同时构造一个线程类,准备接管会话。当一个Socket会话产生后,将这个会话交给线程处理,然后主程序继续监听。运用Thread类或Runnable接口来实现是不错的办法。
代码还不是很完善,只实现了部分功能:
1.服务器端代码
2.客户端代码
第三步 图形化界面实现服务器和单客户端通信
服务器端代码:
客户端代码:
1.什么是socket
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
重要的Socket API:
java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK文档。
. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
. getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例,。
. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
2.如何开发一个Server-Client模型的程序
开发原理:
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
第二步 多个客户同时连接
在实际的网络环境里,同一时间只对一个用户服务是不可行的。一个优秀的网络服务程序除了能处理用户的输入信息,还必须能够同时响应多个客户端的连接请求。在java中,实现以上功能特点是非常容易的。
设计原理:
主程序监听一端口,等待客户接入;同时构造一个线程类,准备接管会话。当一个Socket会话产生后,将这个会话交给线程处理,然后主程序继续监听。运用Thread类或Runnable接口来实现是不错的办法。
代码还不是很完善,只实现了部分功能:
1.服务器端代码
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 ServerDemo { public static void main(String args[]) { try { ServerSocket server = new ServerSocket(4566); try { while (true) { Socket socket = server.accept(); new CreateServerThread(socket); } } catch (IOException e) { } finally { server.close(); } } catch (Exception e) { System.out.println("Error:" + e); } } } // --- CreateServerThread class CreateServerThread extends Thread { private Socket client; private BufferedReader in; private PrintWriter out; private BufferedReader sin; public CreateServerThread(Socket s) throws IOException { client = s; in = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintWriter(client.getOutputStream(), true); sin = new BufferedReader(new InputStreamReader(System.in)); out.println("--- Welcome ---"); start(); } public void run() { try { String line; System.out.println("Client:" + in.readLine()); System.out.print("Server:"); line = sin.readLine(); while (!line.equals("bye")) { out.println(line); out.flush(); System.out.println("Client:" + in.readLine()); System.out.print("Server:"); line = sin.readLine(); } out.println("--- See you ,bye! ---"); sin.close(); out.close(); in.close(); client.close(); } catch (IOException ex) { ex.printStackTrace(); } } }
2.客户端代码
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class ClientDemo { public static void main(String args[]) { Socket socket; BufferedReader in; PrintWriter out; BufferedReader sin; try { socket = new Socket("127.0.0.1", 4566); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); sin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Server:" + in.readLine()); String line; System.out.print("Client:"); line = sin.readLine(); while (!line.equals("bye")) { out.println(line); out.flush(); System.out.println("Server:" + in.readLine()); System.out.println("Client:"); line = sin.readLine(); } sin.close(); out.close(); in.close(); socket.close(); } catch (Exception e) { System.out.println("Error:" + e); } } }
第三步 图形化界面实现服务器和单客户端通信
服务器端代码:
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class TestServer extends Frame implements ActionListener { ServerSocket ss = null; Socket s = null; private DataInputStream is = null; private DataOutputStream os = null; private boolean bConnected = false; Label ip = new Label("本机IP:"); TextField ipAddress; Label lport = new Label("端口"); TextField tport = new TextField("8888"); Button blisten = new Button("监听"); Button close = new Button("关闭"); Panel panel = new Panel(); TextField tfTxt = new TextField(); TextArea taContent = new TextArea(); Thread tRecv = new Thread(new RecvThread()); public TestServer() { setTitle("服务器端"); setLocation(400, 300); setSize(500, 500); setLayout(new BorderLayout()); panel.setLayout(new FlowLayout()); try { ipAddress = new TextField(InetAddress.getLocalHost().toString()); } catch (HeadlessException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } panel.add(ip); panel.add(ipAddress); panel.add(lport); panel.add(tport); panel.add(blisten); panel.add(close); add(panel, BorderLayout.NORTH); add(taContent, BorderLayout.CENTER); add(tfTxt, BorderLayout.SOUTH); blisten.addActionListener(this); close.addActionListener(this); tfTxt.addActionListener(this); pack(); setVisible(true); } /***********************/ public void start() { try { int port = Integer.parseInt(tport.getText()); bConnected = true; ss = new ServerSocket(port); s = ss.accept(); os = new DataOutputStream(s.getOutputStream()); is = new DataInputStream(s.getInputStream()); tRecv.start(); } catch (IOException e) { } finally { try { ss.close(); } catch (IOException e) { } } } /*********************************/ public void disconnect() { try { if (os != null) os.close(); if (is != null) is.close(); if (is != null) s.close(); } catch (IOException e) { } } /**********************************/ private class RecvThread implements Runnable { public void run() { try { while (bConnected) { String str = is.readUTF(); taContent.setText(taContent.getText() + "client:" + str + '\n'); } } catch (EOFException e) { taContent.setText("Client closed!"); } catch (IOException e) { e.printStackTrace(); } } } /**************************/ public void actionPerformed(ActionEvent e) { // 如果按下的是监听按钮 if (e.getSource() == blisten) { start(); } else if (e.getSource() == close) { disconnect(); System.exit(0); } else if (e.getSource() == tfTxt) { String str = tfTxt.getText().trim(); tfTxt.setText(""); try { os.writeUTF(str); os.flush(); taContent.setText(taContent.getText() + "server:" + str + '\n'); } catch (IOException e1) { } } } /******************************/ public static void main(String[] args) { new TestServer(); } }
客户端代码:
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class TestClient extends Frame implements ActionListener { Socket s = null; DataOutputStream os = null; DataInputStream is = null; private boolean bConnected = false; Label ip = new Label("IP"); TextField ipAddress = new TextField("127.0.0.1"); Label lport = new Label("端口"); TextField tport = new TextField("8888"); Button bconnect = new Button("连接"); Button close = new Button("关闭"); Panel panel = new Panel(); TextField tfTxt = new TextField(); TextArea taContent = new TextArea(); Thread tRecv = new Thread(new RecvThread()); public void launchFrame() { setTitle("客户端"); setLocation(400, 300); setSize(500, 500); setLayout(new BorderLayout()); panel.setLayout(new FlowLayout()); panel.add(ip); panel.add(ipAddress); panel.add(lport); panel.add(tport); panel.add(bconnect); panel.add(close); add(panel, BorderLayout.NORTH); add(taContent, BorderLayout.CENTER); add(tfTxt, BorderLayout.SOUTH); bconnect.addActionListener(this); close.addActionListener(this); tfTxt.addActionListener(this); pack(); setVisible(true); } public void connect() { try { String host, port; host = ipAddress.getText(); port = tport.getText(); s = new Socket(host, Integer.parseInt(port)); os = new DataOutputStream(s.getOutputStream()); is = new DataInputStream(s.getInputStream()); bConnected = true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /*********************************/ public void disconnect() { try { if (os != null) os.close(); if (is != null) is.close(); if (is != null) s.close(); } catch (IOException e) { } } /****************************/ private class RecvThread implements Runnable { public void run() { try { while (bConnected) { String str = is.readUTF(); taContent.setText(taContent.getText() + "server:" + str + '\n'); } } catch (IOException e) { } } } /*********************************/ public void actionPerformed(ActionEvent e) { if (e.getSource() == bconnect) { connect(); tRecv.start(); } else if (e.getSource() == close) { disconnect(); System.exit(0); } else if (e.getSource() == tfTxt) { String str = tfTxt.getText().trim(); tfTxt.setText(""); try { os.writeUTF(str); os.flush(); taContent.setText(taContent.getText() + "client:" + str + '\n'); } catch (IOException e1) { } } } /**********************************/ public static void main(String[] args) { new TestClient().launchFrame(); } /*********************************/ }
相关文章推荐
- Java 基于TCP_IP协议的网络编程
- java--11--网络编程
- java网络编程(下)
- java听课笔记(十五)之 网络编程
- java基础教程-网络编程(七)
- Android 网络编程 API笔记 - java.net 包相关 接口 api
- 奋斗黑马程序员----Java之网络编程(二)
- java系统学习(十九) --------网络编程基础
- Java 网络编程
- java udp网络编程及实例代码,实现客户端和服务端通信
- java网络编程-双线程实现UDP通信
- 黑马程序员_java基础网络编程
- Java 网络编程 学习笔记二 Socket 用法
- Java 网络编程
- java网络编程,非常详细,适合初学者的java网络编程知识(转载)
- 基于Socket的java网络编程
- java网络编程之简单客户端服务器
- java网络编程____最简单的爬虫(爬取网站美女图片)
- JAVA网络编程之Socket用法
- Java网络编程DatagramPacket传数据