zoukankan      html  css  js  c++  java
  • Java 网络编程

    第一步 充分理解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.服务器端代码

    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();
    }
    /*********************************/
    }
  • 相关阅读:
    笔记35 跨重定向请求传递数
    判断邮箱的正则表达式
    按钮
    async await 的用法
    笔记34 Spring MVC的高级技术——处理multipart形式的数据
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Unique Binary Search Trees,Unique Binary Search Trees II
    Validate Binary Search Tree
    Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/qixin622/p/2277174.html
Copyright © 2011-2022 走看看