19.2 TCP程序设计基础

1、InetAddress类
  java.net包中的inetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。
InetAddress类的常用方法如下:

方法 返回值 说明
getByName(String host) InetAddress 获取与Host相对应的InetAddress对象
getHostAddress() String 获取InetAddress对象所包含的IP地址
getHostName() String 获取此IP地址的主机名
getLocalHost() InetAddress 返回本地主机的InetAddress对象

  注意:InetAddress类的方法会抛出UnknownHostException异常,所以必须进行异常处理。这个异常在主机不存在或网络连接错误时发生。

2、ServerSocket类

  java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是等待来自网络上的“请求”,它可通过制定的端口来等待连接的套接字。服务器套接字依次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入队列中,然后从中取出一个套接字,与服务器新建的套接字连接起来。若请求连接数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小是50.
  ServerSocket类的构造方法都抛出IOException异常,分别有以下几种形式:
    ServerSocket():创建非绑定服务器套接字
    ServerSocket(int port):创建绑定到特定端口的服务器套接字
    ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号
    ServerSocket(int prot, int backlog, InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于极端及上有多块网卡和多个IP地址的情况,用于可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。
ServerSocket类的常用方法如下:

方法 返回值 说  明
accept() Socket 等待客户机的连接。若连接,则创建一套接字
isBound() boolean 判断ServerSocket的绑定状态
getInetAddress() InetAddress 返回此服务器套接字的本地地址
isClosed() boolean 返回服务器套接字的关闭状态
close() void 关闭服务器套接字
bind(SocketAddress endpoint) void 将ServerSocket绑定到特定地址(IP地址和端口号)
getInetAddress() int 返回服务器套接字等待的端口号

  调用ServerSocket类的accept()方法会返回一个和客户端Socket对象向连接的Socket对象,服务器的Socket对象使用getOutputStream()方法获得的输出流将指向客户端Socket对象使用getInputStream()方法获得的那个输入流;同样,服务器端的Socket对象使用getInputStream()方法获得的输入流将指向客户端Socket对象使用getOutputStream()方法获得的那个输出流。也就是说,当服务器向输出流协议信息时,客户端通过相应的输入流就能读取,反之亦然。
  注意:(1)、accept()方法会阻塞线程的继续执行,知道接收到客户的呼叫。如果没有客户呼叫服务器,那么System.out.print(“连接中”)语句将不会执行。语句如果没有客户请求,accept()方法没有发生阻塞,肯定是程序出现了问题。通常是使用了一个还在被其它程序占用的端口号,ServerSoket绑定没有成功。
             (2)、当一台机器上安装了多个网络应用程序时,很可能指定的端口号已被占用。还可能遇到以前运行良好的网络程序突然运行不了的情况,这种情况很可能也是由于端口被别的程序韩勇了。此时可以运行netstat -an来查看该程序锁使用的端口号是否被占用。

3、相关参考例子

 1 package com.lzw;
 2 
 3 import java.io.*;
 4 import java.net.*;
 5 
 6 public class MyTcp { // 创建类MyTcp
 7     private BufferedReader reader; // 创建BufferedReader对象
 8     private ServerSocket server; // 创建ServerSocket对象
 9     private Socket socket; // 创建Socket对象socket
10     
11     void getserver() {
12         try {
13             server = new ServerSocket(8998); // 实例化Socket对象
14             System.out.println("服务器套接字已经创建成功"); // 输出信息
15             while (true) { // 如果套接字是连接状态
16                 System.out.println("等待客户机的连接"); // 输出信息
17                 socket = server.accept(); // 实例化Socket对象
18                 reader = new BufferedReader(new InputStreamReader(socket
19                         .getInputStream())); // 实例化BufferedReader对象
20                 getClientMessage(); // 调用getClientMessage()方法
21             }
22         } catch (Exception e) {
23             e.printStackTrace(); // 输出异常信息
24         }
25     }
26     
27     private void getClientMessage() {
28         try {
29             while (true) { // 如果套接字是连接状态
30                 if (reader.ready()) {
31                     // 获得客户端信息
32                     System.out.println("客户机:" + reader.readLine());
33                 }
34             }
35         } catch (Exception e) {
36             e.printStackTrace(); // 输出异常信息
37         }
38         try {
39             if (reader != null) {
40                 reader.close(); // 关闭流
41             }
42             if (socket != null) {
43                 socket.close(); // 关闭套接字
44             }
45         } catch (IOException e) {
46             e.printStackTrace();
47         }
48     }
49     
50     public static void main(String[] args) { // 主方法
51         MyTcp tcp = new MyTcp(); // 创建本类对象
52         tcp.getserver(); // 调用方法
53     }
54 }
View Code

 1 package com.lzw;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import java.io.*;
 6 import java.net.*;
 7 
 8 import javax.swing.*;
 9 import javax.swing.border.*;
10 
11 public class MyClien extends JFrame { // 创建类继承JFrame类
12     /**
13      * 
14      */
15     private static final long serialVersionUID = 1L;
16     private PrintWriter writer; // 声明PrintWriter类对象
17     Socket socket; // 声明Socket对象
18     private JTextArea ta = new JTextArea(); // 创建JtextArea对象
19     private JTextField tf = new JTextField(); // 创建JtextField对象
20     Container cc; // 声明Container对象
21     
22     public MyClien(String title) { // 构造方法
23         super(title); // 调用父类的构造方法
24         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
25         cc = this.getContentPane(); // 实例化对象
26 
27         final JScrollPane scrollPane = new JScrollPane();
28         scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
29         getContentPane().add(scrollPane, BorderLayout.CENTER);
30         scrollPane.setViewportView(ta);
31         cc.add(tf, "South"); // 将文本框放在窗体的下部
32         tf.addActionListener(new ActionListener() {
33             // 绑定事件
34             public void actionPerformed(ActionEvent e) {
35                 // 将文本框中信息写入流
36                 writer.println(tf.getText());
37                 // 将文本框中信息显示在文本域中
38                 ta.append(tf.getText() + '\n');
39                 ta.setSelectionEnd(ta.getText().length());
40                 tf.setText(""); // 将文本框清空
41             }
42         });
43     }
44     
45     private void connect() { // 连接套接字方法
46         ta.append("尝试连接\n"); // 文本域中提示信息
47         try { // 捕捉异常
48             socket = new Socket("127.0.0.1", 8998); // 实例化Socket对象
49             writer = new PrintWriter(socket.getOutputStream(), true);
50             ta.append("完成连接\n"); // 文本域中提示信息
51         } catch (Exception e) {
52             e.printStackTrace(); // 输出异常信息
53         }
54     }
55     
56     public static void main(String[] args) { // 主方法
57         MyClien clien = new MyClien("向服务器送数据"); // 创建本例对象
58         clien.setSize(200, 200); // 设置窗体大小
59         clien.setVisible(true); // 将窗体显示
60         clien.connect(); // 调用连接方法
61     }
62 }
View Code

 1 package com.lzw;
 2 
 3 import java.net.*;
 4 
 5 public class MyHost {
 6     public static void main(String args[]) {
 7         InetAddress ip = null;
 8         
 9         try {
10             ip = InetAddress.getByName("localhost");// 修改为指定的主机名称
11             System.out.println("主机名:" + ip.getHostName());
12             System.out.println("主机IP地址:" + ip.getHostAddress());
13             System.out.println("本机IP地址:"
14                     + InetAddress.getLocalHost().getHostAddress());
15         } catch (UnknownHostException e) {
16             e.printStackTrace();
17         }
18         
19     }
20 }
View Code

 1 package com.lzw;
 2 
 3 import java.io.*;
 4 import java.net.*;
 5 
 6 /**
 7  * @author Administrator
 8  */
 9 public class ComputerServer {
10     public static void main(String[] args) {
11         try {
12             ServerSocket ss = new ServerSocket(8001);
13             while (!ss.isClosed()) {
14                 Socket s = ss.accept();
15                 InputStream ips = s.getInputStream();
16                 OutputStream ops = s.getOutputStream();
17                 String str = "欢迎进入程序\n2.编写TCP服务器程序,"
18                         + "实现创建一个在8001端口上等待的ServerSocket"
19                         + "对象,当接收到一个客户机的连接请求后,"
20                         + "程序从与客户机建立了连接的Socket对象中获得输入输出"
21                         + "流。通过输出流向客户机发送信息。";
22                 ops.write(str.getBytes());
23                 byte[] buf = new byte[1024];
24                 int len = 0;
25                 if (ips.available() > 0)
26                     len = ips.read(buf);
27                 System.out.println(new String(buf, 0, len));
28                 ips.close();
29                 ops.close();
30                 s.close();
31             }
32             ss.close();
33         } catch (IOException e) {
34             e.printStackTrace();
35         }
36     }
37 }
View Code
  1 package com.lzw;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import java.io.*;
  6 import java.net.*;
  7 
  8 import javax.swing.*;
  9 
 10 public class TestClient extends JFrame {
 11     
 12     /**
 13      * 
 14      */
 15     private static final long serialVersionUID = 1L;
 16     private JTextArea textArea;
 17     private JTextField portField;
 18     private JTextField hostField;
 19     
 20     /**
 21      * Launch the application
 22      * 
 23      * @param args
 24      */
 25     public static void main(String args[]) {
 26         EventQueue.invokeLater(new Runnable() {
 27             public void run() {
 28                 try {
 29                     TestClient frame = new TestClient();
 30                     frame.setVisible(true);
 31                 } catch (Exception e) {
 32                     e.printStackTrace();
 33                 }
 34             }
 35         });
 36     }
 37     
 38     /**
 39      * Create the frame
 40      */
 41     public TestClient() {
 42         super();
 43         setBounds(100, 100, 500, 212);
 44         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 45         
 46         final JPanel panel = new JPanel();
 47         panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
 48         getContentPane().add(panel, BorderLayout.NORTH);
 49         
 50         final JLabel label = new JLabel();
 51         label.setText("连接主机:");
 52         panel.add(label);
 53         
 54         hostField = new JTextField();
 55         hostField.setText("localhost");
 56         panel.add(hostField);
 57         
 58         final JLabel label_1 = new JLabel();
 59         label_1.setText("端口:");
 60         panel.add(label_1);
 61         
 62         portField = new JTextField();
 63         portField.setText("8001");
 64         panel.add(portField);
 65         
 66         final JButton button = new JButton();
 67         button.addActionListener(new ActionListener() {
 68             public void actionPerformed(final ActionEvent e) {
 69                 final String hostName = hostField.getText();
 70                 String portNum = portField.getText();
 71                 final int port = Integer.parseInt(portNum);
 72                 new Thread() {
 73                     public void run() {
 74                         try {
 75                             final InetAddress host = InetAddress.getByName(hostName);
 76                             Socket socket = new Socket(host, port);
 77                             final InputStream is = socket.getInputStream();
 78                             InputStreamReader reader=new InputStreamReader(is);
 79                             int data = 0;
 80                             while ((data=reader.read()) != -1) {
 81                                 textArea.append((char)data+"");
 82                                 textArea.revalidate();
 83                                 Thread.sleep(100);
 84                             }
 85                         } catch (Exception e1) {
 86                             textArea.append(e1.toString());
 87                             e1.printStackTrace();
 88                         }
 89                     }
 90                 }.start();
 91                 
 92             }
 93         });
 94         button.setText("连接");
 95         panel.add(button);
 96         
 97         final JScrollPane scrollPane = new JScrollPane();
 98         getContentPane().add(scrollPane, BorderLayout.CENTER);
 99         
100         textArea = new JTextArea();
101         textArea.setLineWrap(true);
102         scrollPane.setViewportView(textArea);
103     }
104 }
View Code

  1 package com.lzw;
  2 
  3 //服务器端程序
  4 import java.awt.*;
  5 import java.io.*;
  6 import java.net.*;
  7 import java.util.*;
  8 import java.util.List;
  9 
 10 import javax.swing.*;
 11 
 12 public class TCPServer extends JFrame {
 13     /**
 14      * 
 15      */
 16     private static final long serialVersionUID = 1L;
 17     private ServerSocket ss = null;
 18     private boolean bStart = false;
 19     
 20     private JTextArea taContent = new JTextArea();
 21     
 22     private int index = 0;
 23     
 24     List<Client> clients = new ArrayList<Client>();
 25     
 26     public void launchFrame() {
 27 //        Container con = this.getContentPane();
 28         taContent.setEditable(false);
 29         
 30         taContent.setBackground(Color.DARK_GRAY);
 31         taContent.setForeground(Color.YELLOW);
 32         this.add(taContent);
 33         this.setSize(300, 350);
 34         this.setLocation(400, 200);
 35         this.setTitle("TCP Server");
 36         this.setVisible(true);
 37         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 38         tcpMonitor();
 39     }
 40     
 41     public void tcpMonitor() {
 42         try {
 43             ss = new ServerSocket(8888);
 44             bStart = true;
 45         } catch (IOException e) {
 46             
 47             e.printStackTrace();
 48         }
 49         
 50         try {
 51             while (bStart) {
 52                 index++;
 53                 Socket s = ss.accept();
 54                 Client c = new Client(s);
 55                 clients.add(c);
 56                 
 57                 taContent.append(s.getInetAddress().getHostAddress()
 58                         + " connected " + index + " clients\n");
 59                 new Thread(c).start();
 60                 
 61             }
 62         } catch (IOException e) {
 63             e.printStackTrace();
 64         } finally {
 65             try {
 66                 ss.close();
 67             } catch (IOException e) {
 68                 
 69                 e.printStackTrace();
 70             }
 71         }
 72         
 73     }
 74     
 75     public static void main(String args[]) {
 76         TCPServer ts = new TCPServer();
 77         ts.launchFrame();
 78     }
 79     
 80     private class Client implements Runnable {
 81         DataInputStream dis = null;
 82         DataOutputStream dos = null;
 83         
 84         Socket s = null;
 85         boolean bStart = false;
 86         
 87         Client(Socket s) {
 88             this.s = s;
 89             try {
 90                 dis = new DataInputStream(s.getInputStream());
 91                 dos = new DataOutputStream(s.getOutputStream());
 92             } catch (IOException e) {
 93                 e.printStackTrace();
 94             }
 95             
 96             bStart = true;
 97         }
 98         
 99         public void sendToEveryClient(String str) {
100             try {
101                 dos.writeUTF(str);
102                 dos.flush();
103                 
104             } catch (IOException e) {
105                 index--;
106                 clients.remove(this);
107                 taContent.append(s.getInetAddress().getHostAddress()
108                         + " exited " + index + " clients\n");
109                 System.out.println("对方退出了!我从List里面去掉了!");
110             }
111         }
112         
113         public void run() {
114             try {
115                 while (bStart) {
116                     String str = dis.readUTF();
117                     System.out.println(str);
118                     for (int i = 0; i < clients.size(); i++) {
119                         Client c = clients.get(i);
120                         c.sendToEveryClient(str);
121                     }
122                 }
123             } catch (EOFException e) {
124                 clients.remove(this);
125                 taContent.append(s.getInetAddress().getHostAddress()
126                         + " exited " + clients.size() + " clients\n");
127                 System.out.println("client closed");
128             } catch (SocketException e) {
129                 System.out.println("client closed");
130             } catch (IOException e) {
131                 e.printStackTrace();
132             } finally {
133                 try {
134                     if (s != null)
135                         s.close();
136                     if (dis != null)
137                         dis.close();
138                     if (dos != null)
139                         dos.close();
140                 } catch (IOException e) {
141                     e.printStackTrace();
142                 }
143             }
144         }
145         
146     }
147     
148 }
View Code

  1 package com.lzw;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import java.io.*;
  6 import java.net.*;
  7 
  8 import javax.swing.*;
  9 
 10 public class TCPClient extends JFrame {
 11     /**
 12      * 
 13      */
 14     private static final long serialVersionUID = 1L;
 15     TextArea taContent = new TextArea();
 16     JTextField tfTxt = new JTextField(20);
 17     
 18     JButton send = new JButton("发送");
 19     JButton connect = new JButton("连接");
 20     JButton clear = new JButton("清空");
 21     
 22     boolean live = false;
 23     JPanel p1 = new JPanel();
 24     JPanel p2 = new JPanel();
 25     
 26     Socket s = null;
 27     DataOutputStream dos = null;
 28     DataInputStream dis = null;
 29     
 30     boolean bConnected = false;
 31     
 32     Thread t = new Thread(new RecToServer());
 33     
 34     public void launchFrame() {
 35         
 36         taContent.setEditable(false);
 37         
 38         p2.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 5));
 39         p2.add(send);
 40         p2.add(connect);
 41         p2.add(clear);
 42         
 43         Container con = this.getContentPane();
 44         
 45         con.add(taContent, "North");
 46         con.add(tfTxt, "Center");
 47         con.add(p2, "South");
 48         
 49         this.setSize(300, 350);
 50         this.setLocation(400, 200);
 51         this.setTitle("Chat Client");
 52         
 53         this.setVisible(true);
 54         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 55         
 56         connect.addActionListener(new Connect());
 57         send.addActionListener(new SendMsg());
 58         clear.addActionListener(new ActionListener() {
 59             public void actionPerformed(ActionEvent e) {
 60                 taContent.setText("");
 61             }
 62         });
 63     }
 64     
 65     public void connectToServer() {
 66         try {
 67             
 68             s = new Socket("127.0.0.1", 8888);
 69             dos = new DataOutputStream(s.getOutputStream());
 70             dis = new DataInputStream(s.getInputStream());
 71             
 72             bConnected = true;
 73             
 74         } catch (BindException e) {
 75             System.out.println("找不到指定的服务器");
 76         } catch (UnknownHostException e) {
 77             // TODO Auto-generated catch block
 78             e.printStackTrace();
 79         } catch (IOException e) {
 80             // TODO Auto-generated catch block
 81             e.printStackTrace();
 82         }
 83         
 84     }
 85     
 86     public void disConnect() {
 87         try {
 88             if (s != null) {
 89                 s.close();
 90             }
 91             
 92             if (dos != null) {
 93                 dos.close();
 94             }
 95             if (dis != null) {
 96                 dis.close();
 97             }
 98         } catch (IOException e) {
 99             e.printStackTrace();
100         }
101     }
102     
103     public static void main(String args[]) {
104         TCPClient tc = new TCPClient();
105         tc.launchFrame();
106     }
107     
108     private class Connect implements ActionListener {
109         public void actionPerformed(ActionEvent e) {
110             if (e.getActionCommand() == "连接") {
111                 
112                 connectToServer();
113                 try {
114                     t.start();
115                 } catch (IllegalThreadStateException ex) {
116                     
117                 }
118                 
119                 connect.setText("断开连接");
120                 
121             } else if (e.getActionCommand() == "断开连接") {
122                 disConnect();
123                 connect.setText("连接");
124             }
125             
126         }
127     }
128     
129     private class SendMsg implements ActionListener {
130         public void actionPerformed(ActionEvent e) {
131             if (connect.getActionCommand() == "连接") {
132                 JOptionPane.showMessageDialog(TCPClient.this,
133                         "没有找到指定的服务器", "错误提示", 1);
134             } else {
135                 String str = tfTxt.getText();
136                 tfTxt.setText("");
137                 
138                 try {
139                     dos.writeUTF(str);
140                     dos.flush();
141                 } catch (SocketException ex) {
142                     System.out.println("没有找到指定的服务器");
143                     JOptionPane.showMessageDialog(TCPClient.this,
144                             "没有找到指定的服务器", "错误提示", 1);
145                 } catch (IOException ex) {
146                     ex.printStackTrace();
147                 }
148             }
149             
150         }
151     }
152     
153     private class RecToServer implements Runnable {
154         public void run() {
155             try {
156                 while (bConnected) {
157                     String str = dis.readUTF();
158                     // System.out.println(str);
159                     
160                     taContent.append(str + "\n");
161                 }
162             } catch (SocketException e) {
163                 System.out.println("服务器已关闭");
164             } catch (IOException e) {
165                 e.printStackTrace();
166             }
167         }
168     }
169 }
View Code

 

posted @ 2018-09-04 20:40  襄阳古城  阅读(209)  评论(0编辑  收藏  举报