首页 > 代码库 > 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套接字网络编程