首页 > 代码库 > java_socket套接字网络编程

java_socket套接字网络编程

============================================================ 

                                          1.实现server和client模型程序

============================================================ 

实现原理:

============================================================ 

服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,

在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),

等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。  

============================================================ 
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,

关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

============================================================ 

服务器端代码:

 1 package com.b510.socket1703; 2  3 import java.io.*; 4 import java.net.Socket; 5 import java.net.ServerSocket; 6  7 /** 8  * 服务器断的工作就是在指定的端口上监听 9  * <li>建立连接</li>10  * <li>打开输出流</li>11  * <li>封装输出流</li>12  * <li>向客户端发送数据</li>13  * <li>关闭打开的输出流</li>14  * <li>关闭打开的socket对象</li>15  * 16  * @author Hongten17  * 18  * @time 2012-4-29  201219  */20 public class TestServer {21     public static void main(String args[]) {22         try {23             // 指定服务器端的端口号为888824             ServerSocket s = new ServerSocket(8888);25             while (true) {26                 // 建立连接27                 Socket socket = s.accept();28                 // 打开输出流29                 OutputStream os = socket.getOutputStream();30                 // 封装输出流31                 DataOutputStream dos = new DataOutputStream(os);32                 // s<li>.getInetAddress()获取远程ip地址,s<li>.getPort()远程客户端的断后好33                 // 向客户端发送数据34                 dos.writeUTF("你好,客户端地址信息: " + socket.getInetAddress()35                         + "\t客户端通信端口号: " + socket.getPort());36                 dos.writeUTF("i‘m a server ,my name is hongten!");37                 // 关闭打开的输出流38                 dos.close();39                 // 关闭打开的socket对象40                 socket.close();41             }// 开始下一此循环42         } catch (IOException e) {43             e.printStackTrace();44         }45     }46 }

客户端代码:

 1 package com.b510.socket1703; 2  3 import java.io.*; 4 import java.net.Socket; 5  6 /** 7  * 客户端 8  * @author Hongten 9  * 10  * @time 2012-4-29 201211  */12 public class TestClient {13     public static void main(String args[]) {14         try {15             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号16             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么17             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection18             // refused: connect19             Socket s1 = new Socket("127.0.0.1", 8888);20             // 打开输入流21             InputStream is = s1.getInputStream();22             // 封装输入流23             DataInputStream dis = new DataInputStream(is);24             // 打印服务器端发送过来的信息25             System.out.println(dis.readUTF());26             System.out.println(dis.readUTF());27             // 关闭输入流28             dis.close();29             // 关闭打开的socket对象30             s1.close();31         } catch (IOException e) {32             e.printStackTrace();33         }34     }35 }

如果服务器端没有打开,这时候运行客户端,出现的结果:

 1 java.net.ConnectException: Connection refused: connect 2     at java.net.PlainSocketImpl.socketConnect(Native Method) 3     at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) 4     at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) 5     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) 6     at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) 7     at java.net.Socket.connect(Socket.java:518) 8     at java.net.Socket.connect(Socket.java:468) 9     at java.net.Socket.<init>(Socket.java:365)10     at java.net.Socket.<init>(Socket.java:179)11     at com.b510.socket1703.TestClient.main(TestClient.java:19)

如果服务器端先打开服务,这时候客户端连接服务器端,出现的效果:

1 你好,客户端地址信息: /127.0.0.1    客户端通信端口号: 28002 i‘m a server ,my name is hongten!

============================================================ 

                                              2.实现单线程的聊天室

============================================================ 

服务器端代码:

 1 package com.b510.socket1704.simplechatroom; 2  3 import java.io.*; 4 import java.net.Socket; 5 import java.net.ServerSocket; 6 import java.net.SocketException; 7  8 /** 9  * 服务器端程序,在while循环中所执行的动作是:10  * 听,说,听,说,听,说...11  * 12  * @author Hongten13  * 14  * @time 2012-4-29 201215  */16 public class TestServer {17     public static void main(String args[]) {18         try {19             //创建一个socket对象20             ServerSocket s = new ServerSocket(8888);21             //socket对象调用accept方法,等待连接请求22             Socket s1 = s.accept();23             //打开输出流24             OutputStream os = s1.getOutputStream();25             //封装输出流26             DataOutputStream dos = new DataOutputStream(os);27             //打开输入流28             InputStream is = s1.getInputStream();29             //封装输入流30             DataInputStream dis = new DataInputStream(is);31             //读取键盘输入流32             InputStreamReader isr = new InputStreamReader(System.in);33             //封装键盘输入流34             BufferedReader br = new BufferedReader(isr);35 36             String info;37             while (true) {38                 //接受客户端发送过来的信息39                 info = dis.readUTF();40                 //打印接受的信息41                 System.out.println("对方说: " + info);42                 //如果发现接受的信息为:bye,那么就结束对话43                 if (info.equals("bye"))44                     break;45                 //读取键盘的输入流46                 info = br.readLine();47                 //写入到网络连接的另一边,即客户端48                 dos.writeUTF(info);49                 //如果服务器自己说:bye,也是结束对话50                 if (info.equals("bye"))51                     break;52             }53             //关闭输入流54             dis.close();55             //关闭输出流56             dos.close();57             //关闭socket对象58             s1.close();59             s.close();60         } catch (SocketException e) {61             System.out.println("网络连接异常,程序退出!");62         } catch (IOException e) {63             e.printStackTrace();64         }65     }66 }

 

客户端代码:

 1 package com.b510.socket1704.simplechatroom; 2  3 import java.io.*; 4 import java.net.Socket; 5 import java.net.SocketException; 6 /** 7  * 客户端程序,在while循环中所执行的动作是: 8  * 说,听,说,听,说,听.... 9  * @author Hongten10  *11  * @time 2012-4-29  201212  */13 public class TestClient {14     public static void main(String args[]) {15         try {16             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号17             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么18             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection19             // refused: connect20             Socket s1 = new Socket("localhost", 8888);21             //打开输出流22             OutputStream os = s1.getOutputStream();23             //封装输出流24             DataOutputStream dos = new DataOutputStream(os);25             //打开输入流26             InputStream is = s1.getInputStream();27             //封装输入流28             DataInputStream dis = new DataInputStream(is);29             //读取键盘输入流30             InputStreamReader isr = new InputStreamReader(System.in);31             //封装键盘输入流32             BufferedReader br = new BufferedReader(isr);33 34             String info;35             while (true) {36                 //客户端先读取键盘输入信息37                 info = br.readLine();38                 //把他写入到服务器方39                 dos.writeUTF(info);40                 //如果客户端自己说:bye,即结束对话41                 if (info.equals("bye"))42                     break;43                 //接受服务器端信息44                 info = dis.readUTF();45                 //打印46                 System.out.println("对方说: " + info);47                 if (info.equals("bye"))48                     break;49             }50             //关闭相应的输入流,输出流,socket对象51             dis.close();52             dos.close();53             s1.close();54         } catch (IOException e) {55             e.printStackTrace();56         }57     }58 }

运行效果:

服务器端效果>>>

1 对方说: hell2 你好3 对方说: 嘿嘿4 你今天5 对方说: 136 代售点

客户端端效果>>>

1 hell2 对方说: 你好3 嘿嘿4 对方说: 你今??5 136 对方说: 代售??

当前的程序不管是服务器端,还是客户端,都是单线程的。如: 服务器端说:"你好"

1 //读取键盘的输入流2 info = br.readLine();3 //写入到网络连接的另一边,即客户端4 dos.writeUTF(info);5 //如果服务器自己说:bye,也是结束对话

通过上面的代码,把"你好"发送出去了,这时候,程序又开始循环,运行到:

1 //接受客户端发送过来的信息2 info = dis.readUTF();

这段代码,其实在这里就阻塞在这里了。要等到客户端那边说了话,"嘿嘿",这时候这里的
阻塞才会变为非阻塞状态,然后又继续说,说完后又继续阻塞......

而对于客户端来说,其实是一样的道理,客户端说完"hello"后,进入:

1 //接受服务器端信息2 info = dis.readUTF();

到收听服务器端的信息,在这里也产生了阻塞,只有服务器端说了"你好",这个阻塞才变为非阻塞
状态。然后又继续接下来的动作....

============================================================ 

                                              3.实现多线程的聊天室

============================================================ 

服务器端代码:

 

 1 package com.b510.socket1705.freeechatroom; 2  3 import java.io.*; 4 import java.net.*; 5  6 /** 7  * 服务器端程序 8  *  9  * @author Hongten10  * 11  * @time 2012-4-29 201212  */13 public class TestServer {14     public static void main(String args[]) {15         try {16             // 创建一个socket对象17             ServerSocket s = new ServerSocket(8888);18             // socket对象调用accept方法,等待连接请求19             Socket s1 = s.accept();20 21             // =========服务器端,在这里应该先打开输出流,在打开输入流,22             // =========因为服务器端执行的操作是先听,再说,听,说,听,说.....23 24             // 打开输出流25             OutputStream os = s1.getOutputStream();26             // 封装输出流27             DataOutputStream dos = new DataOutputStream(os);28             // 打开输入流29             InputStream is = s1.getInputStream();30             // 封装输入流31             DataInputStream dis = new DataInputStream(is);32             // 创建并启用两个线程33             new MyServerReader(dis).start();34             new MyServerWriter(dos).start();35         } catch (IOException e) {36             e.printStackTrace();37         }38     }39 }40 41 // 接受并打印客户端传过来的信息42 class MyServerReader extends Thread {43     private DataInputStream dis;44 45     public MyServerReader(DataInputStream dis) {46         this.dis = dis;47     }48 49     public void run() {50         String info;51         try {52             while (true) {53                 // 如果对方,即客户端没有说话,那么就会阻塞到这里,54                 // 这里的阻塞并不会影响到其他线程55                 info = dis.readUTF();56                 // 如果状态有阻塞变为非阻塞,那么就打印接受到的信息57                 System.out.println("对方说: " + info);58                 if (info.equals("bye")) {59                     System.out.println("对方下线,程序退出!");60                     System.exit(0);61                 }62             }63         } catch (IOException e) {64             e.printStackTrace();65         }66     }67 }68 69 // 从键盘获得输入流并写入信息到客户端70 class MyServerWriter extends Thread {71     private DataOutputStream dos;72 73     public MyServerWriter(DataOutputStream dos) {74         this.dos = dos;75     }76 77     public void run() {78         // 读取键盘输入流79         InputStreamReader isr = new InputStreamReader(System.in);80         // 封装键盘输入流81         BufferedReader br = new BufferedReader(isr);82         String info;83         try {84             while (true) {85                 info = br.readLine();86                 dos.writeUTF(info);87                 if (info.equals("bye")) {88                     System.out.println("自己下线,程序退出!");89                     System.exit(0);90                 }91             }92         } catch (IOException e) {93             e.printStackTrace();94         }95     }96 }

 

客户端代码:

 1 package com.b510.socket1705.freeechatroom; 2  3 import java.io.*; 4 import java.net.*; 5  6 /** 7  * 客户端程序 8  *  9  * @author Hongten10  * 11  * @time 2012-4-29 201212  */13 public class TestClient {14     public static void main(String args[]) {15         try {16             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号17             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么18             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection19             // refused: connect20             Socket s1 = new Socket("127.0.0.1", 8888);21 22             // =========客户端,在这里应该先打开输入流,在打开输出流,23             // =========因为客户端执行的操作是先说,再听,说,听,说,听.....24 25             // 打开输入流26             InputStream is = s1.getInputStream();27             // 封装输入流28             DataInputStream dis = new DataInputStream(is);29             // 打开输出流30             OutputStream os = s1.getOutputStream();31             // 封装输出流32             DataOutputStream dos = new DataOutputStream(os);33 34             // 创建并启用两个线程35             new MyClientReader(dis).start();36             new MyClientWriter(dos).start();37         } catch (IOException e) {38             e.printStackTrace();39         }40     }41 }42 43 // 接受并打印服务器端传过来的信息44 class MyClientReader extends Thread {45     private DataInputStream dis;46 47     public MyClientReader(DataInputStream dis) {48         this.dis = dis;49     }50 51     public void run() {52         String info;53         try {54             while (true) {55                 info = dis.readUTF();56                 System.out.println("对方说: " + info);57                 if (info.equals("bye")) {58                     System.out.println("对方下线,程序退出!");59                     System.exit(0);60                 }61             }62         } catch (IOException e) {63             e.printStackTrace();64         }65     }66 }67 68 // 从键盘获得输入流并写入信息到服务器端69 class MyClientWriter extends Thread {70     private DataOutputStream dos;71 72     public MyClientWriter(DataOutputStream dos) {73         this.dos = dos;74     }75 76     public void run() {77         InputStreamReader isr = new InputStreamReader(System.in);78         BufferedReader br = new BufferedReader(isr);79         String info;80         try {81             while (true) {82                 info = br.readLine();83                 dos.writeUTF(info);84                 if (info.equals("bye")) {85                     System.out.println("自己下线,程序退出!");86                     System.exit(0);87                 }88             }89         } catch (IOException e) {90             e.printStackTrace();91         }92     }93 }

客户端运行效果:

1 这是客户端2 我是hongten3 这是我说的第三句话,haha4 对方说: 我是服务器端,这说我说的第一句话,hehe

服务器端运行效果:

1 对方说: 这是客户??2 对方说: 我是hongten3 对方说: 这是我说的第三句话,haha4 我是服务器端,这说我说的第一句话,hehe

java_socket套接字网络编程