喵星之旅-成长的雏鹰-java高级特性-5-网络编程

网络概述

网络的作用:相互连接的计算机、交换数据、共享资源。

ip地址

两台计算机通信, 双方都必须有地址。
唯一标识网络上的每一台计算机。
IP地址的组成:32位,由4个8位二进制数组成。
IP地址 = 网络地址 +主机地址
网络地址:标识计算机或网络设备所在的网段
主机地址:标识特定主机或网络设备

Socket

通信链路的端点就被称为“套接字”(英文名Socket)。是提供给应用程序的接口。
Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制。

1
2
3
4
5
6
7
java.net包
Socket
ServerSocket
DatagramPacket
DatagramSocket
InetAddress

基于TCP协议的Socket编程

基于TCP协议的Socket网络通信,用来实现双向安全连接网络通信。
Socket通信模型,进行网络通信时,Socket需要借助数据流来完成数据的传递工作。

Socket网络编程一般可以分成如下步骤进行:
1、建立连接
2、打开Socket关联的输入输出流
3、数据流中读写信息
4、关闭所有的数据流和Socket

Socket中实现对象的传递

1
2
3
4
5
6
ObjectOutputStream  oos = new  ObjectOutputStream(…);
oos.writeObject(…);

ObjectInputStream ois = new ObjectInputStream(…);
Object = ois.readObject();

样例

1、客户端发送信息给服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

import java.net.*;
import java.io.*;
public class LoginClient {
public static void main(String[] args) {
try {
//建立客户端Socket连接,指定服务器的位置以及端口
Socket socket=new Socket("localhost",8800);
//打开输入输出流
OutputStream os=socket.getOutputStream();

//发送客户端登录信息,即向输出流写入信息
String info="用户名:Tom;用户密码:123456";
os.write(info.getBytes());

//关闭资源

os.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}




import java.net.*;
import java.io.*;
public class LoginServer {
public static void main(String[] args) {
try {
//建立一个服务器Socket(ServerSocket)指定端口并开始监听
ServerSocket serverSocket=new ServerSocket(8800);
//使用accept()方法等待客户端触发通信
Socket socket=serverSocket.accept();
//打开输入输出流
InputStream is=socket.getInputStream();

//获取客户端信息,即从输入流读取信息
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String info=null;
while(!((info=br.readLine())==null)){
System.out.println("我是服务器,客户登录信息为:"+info);
}

//关闭资源
br.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

2、客户端发送对象给服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/*
* 客户端
* */
public class LoginClient {
public static void main(String[] args) {
try {
//1、创建一个客户端Socket
Socket socket=new Socket("localhost",5000);
//2、通过输出流发送请求
OutputStream os=socket.getOutputStream();
User user=new User("TOM","123456");
ObjectOutputStream oos=new ObjectOutputStream(os);
oos.writeObject(user);

socket.shutdownOutput();
//通过输入流来接收到服务器给客户端的响应
InputStream is=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String reply;
while((reply=br.readLine())!=null){
System.out.println("服务器的响应:"+reply);
}

//3、释放资源
br.close();
is.close();
os.close();
socket.close();

} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
* 服务器端
* */
public class LoginServer {
public static void main(String[] args) {
try {
//1.创建一个服务器Socket
ServerSocket serverSocket=new ServerSocket(5000);
//2.使用accept()等待客户的通信
Socket socket=serverSocket.accept();
//3.获得输入流,获得相应的用户请求
InputStream is=socket.getInputStream();
ObjectInputStream ois=new ObjectInputStream(is);
User user=(User)ois.readObject();
System.out.println("我是服务器,接收到的信息:"+user.getUserName()+"--"+user.getPwd());

//给客户端一个响应
String reply="欢迎登录!";
byte[] replys=reply.getBytes();
OutputStream os=socket.getOutputStream();
os.write(replys);

//4.释放相应资源
os.close();
ois.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}




import java.io.Serializable;

/*
*用户类:用户名和密码
*/
public class User implements Serializable {
private String userName;
private String pwd;



public User() {
}
public User(String userName, String pwd) {
this.userName = userName;
this.pwd = pwd;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}


}


3、多客户端用户登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import java.io.Serializable;
/**
* 用户类
* */
public class User implements Serializable{
private String loginName; //用户名
private String pwd; //用户密码

public User() {
}
public User(String loginName, String pwd) {
super();
this.loginName = loginName;
this.pwd = pwd;
}

public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}


import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class LoginThread extends Thread {
Socket socket=null;
//每启动一个线程,对应Socket
public LoginThread(Socket socket){
this.socket=socket;
}
//启动线程,即响应客户请求
public void run(){
try {
//打开输入输出流
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
//反序列化
ObjectInputStream ois=new ObjectInputStream(is);
//获取客户端信息,即从输入流读取信息
//BufferedReader br=new BufferedReader(new InputStreamReader(ois));
User user=(User)ois.readObject();
if(!(user==null)){
System.out.println("我是服务器,客户登录信息为:"+user.getLoginName()+","+user.getPwd());
}
//给客户端一个响应,即向输出流写入信息
String reply="欢迎你,登录成功!";
os.write(reply.getBytes());
//关闭资源
ois.close();
os.close();
is.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

}


import java.net.*;
import java.io.*;
public class LoginServer {
public static void main(String[] args) {
try {
//建立一个服务器Socket(ServerSocket)指定端口并开始监听
ServerSocket serverSocket=new ServerSocket(8800);
//使用accept()方法等待客户端触发通信
Socket socket=null;
//监听一直进行中
while(true){
socket=serverSocket.accept();
LoginThread LoginThread=new LoginThread(socket);
LoginThread.start();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}


import java.net.*;
import java.io.*;
public class LoginClient {
public static void main(String[] args) {
try {
//建立客户端Socket连接,指定服务器的位置以及端口
Socket socket=new Socket("localhost",8800);
//打开输入输出流
OutputStream os=socket.getOutputStream();
InputStream is=socket.getInputStream();
//对象序列化
ObjectOutputStream oos=new ObjectOutputStream(os);
//发送客户端登录信息,即向输出流写入信息
User user=new User();
user.setLoginName("Tom");
user.setPwd("123456");
oos.writeObject(user);
socket.shutdownOutput();

//接收服务器段的响应,即从输入流读取信息
String reply=null;
BufferedReader br=new BufferedReader(new InputStreamReader(is));
while(!((reply=br.readLine())==null)){
System.out.println("我是客户端,服务器的响应为:"+reply);
}
//4.关闭资源
oos.close();
is.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}



import java.net.*;
import java.io.*;
public class LoginClient2 {
public static void main(String[] args) {
try {
//建立客户端Socket连接,指定服务器的位置以及端口
Socket socket=new Socket("localhost",8800);
//打开输入输出流
OutputStream os=socket.getOutputStream();
InputStream is=socket.getInputStream();
//对象序列化
ObjectOutputStream oos=new ObjectOutputStream(os);
//发送客户端登录信息,即向输出流写入信息
User user=new User();
user.setLoginName("Kate");
user.setPwd("654321");
oos.writeObject(user);
socket.shutdownOutput();

//接收服务器段的响应,即从输入流读取信息
String reply=null;
BufferedReader br=new BufferedReader(new InputStreamReader(is));
while(!((reply=br.readLine())==null)){
System.out.println("我是客户端,服务器的响应为:"+reply);
}
//4.关闭资源
oos.close();
is.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

基于UDP协议的Socket编程

基于UDP协议的Socket网络编程步骤

利用 DatagramPacket 对象封装数据包

利用 DatagramSocket 发送数据包

利用 DatagramSocket 接收数据包

利用 DatagramPacket 处理数据包

UDP样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;

/**
* 服务器端
* */
public class LoginServer {
public static void main(String[] args) {
byte[] infos=new byte[1024];
DatagramPacket dp=new DatagramPacket(infos, infos.length);
DatagramSocket socket=null;
try {
socket=new DatagramSocket(5000);
//接收客户端的数据包,并将信息封装在dp中
socket.receive(dp);

//构建一个字符串
String info=new String(dp.getData(),0,dp.getData().length);
System.out.println("客户端说:"+info);

//给客户端一个响应
String reply="您好,我在,请说!";
//客户端的地址
SocketAddress sa=dp.getSocketAddress();
//打一个包裹
DatagramPacket dp1=
new DatagramPacket(reply.getBytes(),0,reply.getBytes().length,sa);
//将包裹寄走
socket.send(dp1);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
socket.close();
}

}
}


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/*
* 客户端
* */
public class LoginClient {
public static void main(String[] args) {
String info="您好,我想咨询一个问题!";
byte[] infos=info.getBytes();
DatagramSocket socket=null;
try {
InetAddress ia=InetAddress.getByName("localhost");
//构建客户端要发送的数据包对象
DatagramPacket dp=new DatagramPacket(infos, infos.length,ia,5000);
//客户端需要一个DatagramSocket对象
socket=new DatagramSocket();
//通过DatagramSocket对象发送数据包到服务器
socket.send(dp);

//接收服务器的响应
byte[] replys=new byte[1024];
DatagramPacket dp1=new DatagramPacket(replys, replys.length);
socket.receive(dp1);
String reply=new String(dp1.getData(),0,dp1.getData().length);
System.out.println("服务器回应:"+reply);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//释放资源
socket.close();
}

}
}

文章目录
  1. 网络概述
    1. ip地址
  2. Socket
  3. 基于TCP协议的Socket编程
    1. Socket中实现对象的传递
    2. 样例
  4. 基于UDP协议的Socket编程
    1. 基于UDP协议的Socket网络编程步骤
    2. UDP样例
|