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();
    }
    /*********************************/
    }
  • 相关阅读:
    C# 关键字 virtual、override和new的用法
    架构技术及架构要素总结【转】
    vue文件目录结构
    vue项目中,如何对static文件夹下的静态文件添加时间戳,以达到清除缓存
    webpack中关于require与import的区别
    vue 根据下拉框动态切换form的rule
    el-select 根据value查询其对应的label值
    web前端项目规范
    JavaScript 编码规范
    HTML 编码规范
  • 原文地址:https://www.cnblogs.com/qixin622/p/2277174.html
Copyright © 2011-2022 走看看