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 Hongten
17  *
18  * @time 2012-4-29  2012
19  */
20 public class TestServer {
21     public static void main(String args[]) {
22         try {
23             // 指定服务器端的端口号为8888
24             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 2012
11  */
12 public class TestClient {
13     public static void main(String args[]) {
14         try {
15             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
16             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
17             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
18             // refused: connect
19             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    客户端通信端口号: 2800
2 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 Hongten
13  *
14  * @time 2012-4-29 2012
15  */
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 Hongten
10  *
11  * @time 2012-4-29  2012
12  */
13 public class TestClient {
14     public static void main(String args[]) {
15         try {
16             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
17             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
18             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
19             // refused: connect
20             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 对方说: hell
2 你好
3 对方说: 嘿嘿
4 你今天
5 对方说: 13
6 代售点

客户端端效果>>>

1 hell
2 对方说: 你好
3 嘿嘿
4 对方说: 你今??
5 13
6 对方说: 代售??

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

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 Hongten
10  *
11  * @time 2012-4-29 2012
12  */
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 Hongten
10  *
11  * @time 2012-4-29 2012
12  */
13 public class TestClient {
14     public static void main(String args[]) {
15         try {
16             // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
17             // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
18             // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
19             // refused: connect
20             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 我是hongten
3 这是我说的第三句话,haha
4 对方说: 我是服务器端,这说我说的第一句话,hehe

服务器端运行效果:

1 对方说: 这是客户??
2 对方说: 我是hongten
3 对方说: 这是我说的第三句话,haha
4 我是服务器端,这说我说的第一句话,hehe
时间: 2024-11-05 22:40:18

java_socket套接字网络编程的相关文章

java_socket套接字网络编程_实现多线程聊天

java编程_socket_套接字_网络编程_简易的GUI多线程聊天程序 运行效果: =============================================================== 服务器端代码: 1 package com.b510.socket1706.gui.freeechatroom; 2 3 import java.io.*; 4 import java.net.*; 5 import java.awt.*; 6 import java.awt.even

[转帖]在Linux中的使用 ss 命令检查套接字/网络连接

在Linux中的使用 ss 命令检查套接字/网络连接 https://linux.cn/article-4372-1.html 作者: Adrian Dinu 译者: LCTT geekpi | 2014-12-04 10:11   评论: 4 收藏: 7 分享: 13 ss是iproute2包的一部分(控制TCP/IP网络和流量的工具).iproute2的目标是替代先前用于配置网络接口.路由表和管理ARP表的标准Unix网络工具套装(通常称之为“net-tools”).ss工具用于导出套接字统

Node.js开发入门—套接字(socket)编程

Node.js的net模块提供了socket编程接口,方便我们利用较为底层的套接字接口来实现应用协议.这次我们看一个简单的回显服务器示例,包括服务端和客户端的代码. 使用JavaScript也可以进行套接字编程,哈哈,这酸爽! 代码 分服务器和客户端两部分来说吧. echoServer代码分析 echoServer.js: var net = require("net"); // server is an instance of net.Server // sock is an ins

TCP之套接字socket编程

一.socket套接字 "IP地址 + 端口号 "就称为socket.在TCP协议里,建立连接的两个进程各自有一个socket标识,这两个socket pair就唯一标识一个连接,描述网络连接的一对一关系. Linux的基本哲学就是"一切皆文件",其实socket就是一种特殊的文件,是"open-write/read-close"模式的一种实现. 二.socket的基本操作 1.socket()函数 socket函数对应于普通文件的打开操作.普通

TCP/UDP套接字网络协议

TCP服务端(以字节串传输信息) import socket 1.创建套接字 sockfd = socket.socket(socket_family = AF_INET,socket_type = SOCK_STREAM,proto = 0) 功能:创建一个IPv4的流式套接字,括号中的创建IPv4流式套接字的时候可以不写,有缺省值. 参数:socket_family 地址族类型 AF_INET 表示IPv4网络通信 socket_type 套接字类型 SOCK_STREAM 流式  SOCK

多客户登录(基于TCP的流式套接字Socket编程)

1.序列化对象 package com.ljb.app.socket; import java.io.Serializable; /**  * 用户类(实现序列化)  * @author LJB  * @version 2015年3月12日  */ public class User implements Serializable{  private String name;  private String password;    public String getName() {   ret

第4章 基本tcp套接字编程

4.1 各种套接字api(重要) 4.1.1 socket() 用于创建一个套接字描述符,这个描述符指明的是tcp还是udp,同时还有ipv4还是ipv6 #include <sys/socket.h>?int socket(int family, int type, int protocol);//成功返回描述符,错误-1 family主要是指明的协议族,AF_INET:ipv4.AF_INET6:ipv6 .AF_LOCAL:unix域协议.AF_ROUTE:路由套接字.AF_KEY秘钥套

《TCP/IP网络编程》

<TCP/IP网络编程> 基本信息 作者: (韩)尹圣雨 译者: 金国哲 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115358851 上架时间:2014-6-19 出版日期:2014 年6月 开本:16开 页码:1 版次:1-1 所属分类:计算机 > 计算机网络 > 网络协议 > TCP/IP 更多关于>>><TCP/IP网络编程> 编辑推荐 为初学者准备的网络编程 本书涵盖操作系统.系统编程.TCP/IP协议等多种

linux C 网络编程基础

TCP/IP基础 UDP提供无连接服务 UDP的数据格式: #ifdef __FAVOR_BSD struct udphdr { u_int16_t uh_sport; /* source port */ u_int16_t uh_dport; /* destination port */ u_int16_t uh_ulen; /* udp length */ u_int16_t uh_sum; /* udp checksum */ }; #else struct udphdr { u_int1