java网络编程实现两端聊天

网络编程的三要素:

  1. ip地址:唯一标识网络上的每一台计算机
  2. 端口号:计算机中应用的标号(代表一个应用程序),0-1024系统使用或者保留端口,有效端口0-65535(short)
  3. 通信协议:通信的规则 TCP UDP

UDP:相当于发短信,不需要建立连接,数据包的大小限制在64k内,效率高,不安全,容易丢包

TCP:相当于打电话,需要建立连接,效率相对较低,数据传输安全,三次握手完成。


下面使用TCP进行网络通信: 
服务端:

 1 public static void main(String[] args) throws Exception {
 2         //创建服务端的对象
 3         ServerSocket ss = new ServerSocket(8000);
 4         //等待客户端的接入
 5         Socket client = ss.accept();
 6         //从输入流中得到数据
 7         InputStream is = client.getInputStream();
 8         byte[] by = new byte[1024];
 9         int len = is.read(by);
10         String str = new String(by,0,len);
11         System.out.println(str);
12         //关闭
13         client.shutdownInput();
14         is.close();
15         client.close();
16 
17     }

客户端:

 1 public static void main(String[] args) throws Exception {
 2         //创建客户端套接字对象,给定ip地址
 3         Socket client = new Socket("192.168.6.166",8000);
 4         //获取客户端的输出流
 5         OutputStream os = client.getOutputStream();
 6         //向输出流中写入数据
 7         os.write("在?".getBytes());
 8         os.flush();
 9         //切断输出流
10         client.shutdownOutput();
11         //关闭流对象,关闭套接字
12         is.close();
13         os.close();
14         client.close();
15 
16     }

通过上面的代码能够实现基本的发送信息,和接收信息。不过只能客户端发送信息,服务器被动接收信息,下面来实现客户端和服务器互相发送信息:

服务器端:

 1 public static void main(String[] args) throws IOException {
 2         ServerSocket ss = new ServerSocket(8000);
 3         Scanner sc = new Scanner(System.in);
 4         System.out.println("服务器启动!");
 5         Socket s = ss.accept();
 6         OutputStream os = s.getOutputStream();
 7         InputStream is = s.getInputStream();
 8         boolean bool = true;
 9         while(bool){
10             //服务器接收信息
11             byte[] bt = new byte[1024];
12             int length = is.read(bt);
13             System.out.println("			"+new String(bt,0,length)+":客户端");
14             //服务器发送信息
15             System.out.println("服务器:");
16             os.write(sc.next().getBytes());
17             os.flush();
18         }
19         s.shutdownInput();
20         is.close();
21         os.close();
22         s.close();
23         ss.close();
24 
25     }

客户端:

 1 public static void main(String[] args) throws UnknownHostException, IOException {
 2         System.out.println("客户端启动");
 3         Socket client = new Socket("127.0.0.1",8000);
 4         Scanner sc = new Scanner(System.in);
 5         boolean bool = true;
 6         OutputStream os = client.getOutputStream();
 7         InputStream is = client.getInputStream();
 8         while(bool){
 9             //客户端发送信息
10             System.out.println("客户端:");
11             String str = sc.next();
12             os.write(str.getBytes());
13             os.flush();
14             //客户端接收信息
15             byte[] by = new byte[1024];
16             int index = is.read(by);
17             System.out.println("			"+new String(by,0,index)+":服务器");
18         }
19         client.shutdownOutput();
20         os.close();
21         is.close();
22         sc.close();
23         client.close();
24     }

使用上面的方式进行通信,实现结果: 
客户端: 

客户端发送信息界面

服务器: 
服务器界面


这样实现了两端相互通信的要求,如果一方连续发送两条信息的时候,这个程序就会开始出现问题。于是使用线程解决这个问题,具体如下:

客户端:

 1 public class servletSockettest {
 2     public static void main(String[] args) throws IOException {
 3         ServerSocket ss = new ServerSocket(8888);
 4         System.out.println("服务器启动!");
 5         final Socket s = ss.accept();
 6         boolean b = true;
 7         InputStream is = s.getInputStream();
 8         //服务器把输入放入线程里面执行,不会影响主线程的接收信息功能
 9         Thread t = new Thread(){
10             OutputStream os = s.getOutputStream();
11             Scanner sc  = new Scanner(System.in);
12             @Override
13             public void run() {
14                 // TODO Auto-generated method stub
15                 boolean b = true;
16                 while(b){
17                     try {
18                         System.out.print("服务器输入:");
19                         os.write(sc.next().getBytes());
20                         os.flush();
21                     } catch (IOException e) {
22                         // TODO Auto-generated catch block
23                         e.printStackTrace();
24                     }
25                 }
26             }
27         };
28         t.start();
29         while(b){
30             byte[] bt = new byte[1024];
31             int length = is.read(bt);
32             String str = new String(bt,0,length);
33             System.out.println("			"+str+":客户端");
34         }
35 
36 
37         is.close();
38         s.shutdownInput();
39         s.close();
40         ss.close();
41 
42     }
43 }

客户端:

 1 public class Sockettest {
 2     public static void main(String[] args) throws UnknownHostException, IOException {
 3         final Socket client = new Socket("192.168.6.166",8888);
 4         Scanner sc = new Scanner(System.in);
 5         System.out.println("客户端启动");
 6         OutputStream os = client.getOutputStream();
 7         //新建一个线程用来接收信息,不影响主线程的输入发送信息。
 8         Thread t = new Thread(){
 9             InputStream is = client.getInputStream();
10             @Override
11             public void run() {
12                 // TODO Auto-generated method stub
13                 boolean b = true;
14                 while(b){
15                     try {
16                         byte[] bt = new byte[1024];
17                         int length = is.read(bt);
18                         String str = new String(bt,0,length);
19                         System.out.println("			"+str+":服务器");
20                     } catch (IOException e) {
21                         // TODO Auto-generated catch block
22                         e.printStackTrace();
23                     }
24                 }
25             }
26         };
27         t.start();
28         boolean b = true;
29         while(b){
30             System.out.print("客户端输入:");
31             os.write(sc.next().getBytes());
32             os.flush();
33         }
34         os.close();
35         client.shutdownOutput();
36         client.close();
37     }
38 }

运行结果: 
客户端 
这里写图片描述 
服务器: 
这里写图片描述

这样就可以实现基本上的通信了。如果有兴趣,可以结合JFrame窗体,实现多个窗口相互聊天,不再使界面这么难看。

 
 
原文地址:https://www.cnblogs.com/benxi/p/7347108.html