Fork me on GitHub

Java 网络编程技术

本系列文章在 https://github.com/freestylefly/javaStudy 持(jing)续(chang)更(duan)新(geng)中,欢迎有兴趣的童鞋们关注。

1、查看本机的IP地址和网络相关概念

config查看本机的IP地址
ping命令测试网络是否通畅
网络是连接在一起共享数据和资源的计算机
按照覆盖范围可以分为:局域网、城域网、广域网
ping 127.0.0.1检查TCP/IP协议安装是否正确

2、基于TCP协议的网络编程

①建立连接
②打开socket关联的输入/输出流
③从流中读取信息
④关闭流和socket

注意点:
1、先写服务器,再写客户端
2、在客户端输出部分要加socket.shutdownOutput()(相当于告诉服务器我说的话说完了),若用字符流写,需要在socket.shutdownOutput()前面加上flash方法,清空缓存
3、本机localhost
4、端口号不低于1024

三、实例

1、客户端发送的请求为String字符串

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
package demo1;

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


/*
* 服务器
*/
public class LoginServece {
public static void main(String[] args) throws Exception {
//建立连接
ServerSocket serverSocket= new ServerSocket(8000);
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);
}

// 给回应

String reply ="我是服务器,欢迎登陆";
OutputStream os=socket.getOutputStream();
os.write(reply.getBytes());

//关闭资源
os.close();
br.close();
is.close();
socket.close();
}
}
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
package demo1;

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

/*
* 客户端
*/
public class LoginClient {
public static void main(String[] args) throws Exception, IOException {
Socket socket = new Socket("localhost", 8000);
// 发送请求
OutputStream os = socket.getOutputStream();
String info = "姓名:jim 密码12345";
os.write(info.getBytes());
socket.shutdownOutput();

// 读回应
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String replu = null;
while ((replu = br.readLine()) != null) {
System.out.println("我是客户端,服务器说:" + replu);
}
br.close();
is.close();
os.close();
socket.close();
}
}

2、客户端传出的是一个对象的情况
需要将对象序列化,注意要实现Serializable接口

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
package demo2;

import java.io.Serializable;

public class User implements Serializable{
private String name;
private String psd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPsd() {
return psd;
}
public void setPsd(String psd) {
this.psd = psd;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, String psd) {
super();
this.name = name;
this.psd = psd;
}
@Override
public String toString() {
return "用户名:"+this.getName()+"\t"+"密码:"+this.getPsd();
}


}
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
package demo2;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


/*
* 服务器
*/
public class LoginServece {
public static void main(String[] args) throws Exception {
//建立连接
ServerSocket serverSocket= new ServerSocket(8000);
Socket socket =serverSocket.accept();

//打开输入流
InputStream is=socket.getInputStream();

//读
ObjectInputStream ois = new ObjectInputStream(is);
User user=(User) ois.readObject();
System.out.println(user);

// 给回应


OutputStream os=socket.getOutputStream();
String reply ="我是服务器,欢迎登陆";
os.write(reply.getBytes());

//关闭资源
os.close();
ois.close();
is.close();
socket.close();
}
}
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
package demo2;

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;

/*
* 客户端
*/
public class LoginClient {
public static void main(String[] args) throws Exception, IOException {
Socket socket = new Socket("localhost", 8000);
// 发送请求
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(os);
User user =new User("Jack", "123456");
oos.writeObject(user);

// 读回应
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String replu = null;
while ((replu = br.readLine()) != null) {
System.out.println("我是客户端,服务器说:" + replu);
}

os.close();
oos.close();
socket.close();
}
}

3、利用多线程实现多个客户端发出请求情况
①创建服务器线程类,run()方法实现对一个请求的响应处理
②死循环让服务器一直处于监听状态
③服务器每监听一个线程,创建一个线程对象并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package demo3;

import java.net.ServerSocket;
import java.net.Socket;


/*
* 服务器
*/
public class LoginServece {
public static void main(String[] args) throws Exception {
//建立连接
ServerSocket serverSocket= new ServerSocket(8000);
Socket socket;
while(true) {
socket=serverSocket.accept();
MyThread thread =new MyThread(socket);
thread.start();
}
}
}
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
package demo3;

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

public class MyThread extends Thread{
private Socket socket;

public MyThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//打开输入流
InputStream is=null;
ObjectInputStream ois=null;
OutputStream os=null;
try {
is = socket.getInputStream();
//读
ois = new ObjectInputStream(is);
User user=(User) ois.readObject();
System.out.println(user);

// 给回应


os=socket.getOutputStream();
String reply ="我是服务器,欢迎登陆";
os.write(reply.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {

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



}

}
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
package demo3;

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 LoginClient22 {
public static void main(String[] args) throws Exception, IOException {
Socket socket = new Socket("localhost", 8000);
// 发送请求
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(os);
User user =new User("good", "111111");
oos.writeObject(user);

// 读回应
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String replu = null;
while ((replu = br.readLine()) != null) {
System.out.println("我是客户端,服务器说:" + replu);
}

os.close();
oos.close();
socket.close();
}
}

四、InetAddress类

位于java.net包中,常用于封装IP地址和DNS
静态方法
InetAddress.getByName(String hostName)
返回指定主机名的InetAddress对象

五、基于UDP协议的socket编程

四个步骤
1、DatagramPacket对象封装数据包
2、DatagramSocket发送数据包
3、DatagramSocket接收数据包
4、DatagramPacket处理数据包
TCP和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
package socket4;

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

/*
* 基于UDP协议的网络编程
*/
public class LoginnServerce {
public static void main(String[] args) {
DatagramSocket socket=null;

try {
//接收客户端发过来的请求
//1、建立一个空包用来收
byte[] b =new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
//2、创建DatagramSocket,(快递点)
socket =new DatagramSocket(8000);
//3、收数据
socket.receive(dp);
//读取数据
String info = new String(dp.getData(),0,dp.getData().length);
System.out.println("客户端说:"+info);


//给客户端一个响应
String reply = "我是服务器,你好,客户端!";
DatagramPacket dp1=new DatagramPacket(reply.getBytes(), reply.getBytes().length, InetAddress.getByName("localhost"), 8000);
//不用再创建socket
socket.send(dp1);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(null!=socket) {
socket.close();
}
}
}
}
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
package socket4;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
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();
//获得一个InetAddress
InetAddress address;
DatagramSocket socket=null;
try {
address = Inet4Address.getByName("localhost");
//建立一个包裹封装数据
DatagramPacket dp =new DatagramPacket(infos,infos.length,address,8000);
//建立快递点
socket =new DatagramSocket();
//通过快递点发送数据
socket.send(dp);

//接收服务器发来的信息
//创建一个空包接收
byte[] b = new byte[1024];
DatagramPacket dp1 =new DatagramPacket(b, b.length);
socket.receive(dp1);
// 读取信息
String reply = new String(dp1.getData(), 0, dp1.getData().length);
System.out.println(reply);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
socket.close();
}

}
}

本文章已同步至我的GitHub仓库:Javastudy,期待您的加入:blush:

本文章已同步至苍何的个人博客,可以直接在博客上留言哦:blush:

来我的微信公众号玩耍呗:blush:

扫码无套路关注我的CSDN博客:blush:

苍 何 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!