您的位置:首页 > 理论基础 > 计算机网络

java网络编程

2016-07-19 00:02 471 查看

java网络编程

网络编程介绍

通过使用套接字来达到进程间通信目的的编程就是网络编程

网络编程最重要的两点
1、定位目标主机(ip地址和端口)
2、如何传输数据(协议)


网络编程主要的两种模型

基于TCP编程模型

面向连接相对可靠传输协议编程
TCP:传输控制协议
案列模型:打电话通话

要点:基于TCP网络编程的核心在于建立连接,通过连接里获得流对象来实现数据的传输的目的。

备注:TCP编程的核心在于连接,以及从连接获得的流对象。




基于UDP编程模型

面向无连接不是很可靠的传输协议
UDP:用户数据报协议
案列模型:发送短信、日常寄送包裹

要点:基于UDP网络编程的核心在于构建数据包对象,从DatagramSocket对象中发送和接收数据包对象。

备注:UDP编程的核心在于数据报中




Java网络编程基础类与核心类

java网络编程基础类

InetAddress类

InetAddress对象表示IP地址,由于java是面向对象编程的语言,所以为了给IP匹配就以InetAddress来表示IP地址。直接使用字符串表示IP地址也没关系。


URL类

URL对象表示同意资源定位符,同InetAddress类似,url同样也可以使用字符串表示,只不过java是面向对象语言因此使用了URL类。


URLConnection类

URLConnection是一个抽象类,表示一个连接,其主要实现由HttpURLConnection类,http连接。
发送请求时就会使用到这个类。


java网络编程核心类

Socket套接字

A socket is an endpoint for communication between two machines.


ServerSocket服务器套接字

This class implements server sockets. A server socket waits for requests to come in over the network.
It performs some operation

备注:可以把Socket和ServerSocket简单理解为连接端点。


DatagramSocket数据报套接字

This class represents a socket for sending and receiving datagram packets.

A datagram socket is the sending or receiving point for a packet delivery service.
Each packet sent or received on a datagram socket is individually addressed and routed.
Multiple packets sent from one machine to another may be routed differently,
and may arrive in any order.
备注:理解为邮局


DatagramPacket数据报

This class represents a datagram packet.
备注:理解为数据包裹


Java网络编程聊天程序

基于tcp的聊天

Client端代码

/**
* 控制台输入信息,聊天小程序。
*
* @author xuyi3
* @2016年7月18日 @上午9:35:08
* @Client2
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class Client {
public static void main(String[] args) throws Exception {

// 客户端新建Socket对象,必须制定主机地址和端口
Socket socket = new Socket("192.168.1.187", 9999);

// 通过Socket对象获得连接的输入流
InputStream in = socket.getInputStream();
// 通过Socket对象获得连接的输出流
OutputStream out = socket.getOutputStream();

// 使用更方便的缓冲包装流来操作
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));

// 控制台输入流
Scanner scanner = new Scanner(System.in);

while (true) {

// 输出信息给服务器
System.out.print("客户端:");
String line = null;
line = scanner.nextLine();

writer.write(line);
// 以下两步非常重要,不写会让对方的输入流一直阻塞。
writer.newLine();
writer.flush();

// 读取服务器信息

String string = reader.readLine();
System.out.println("服务器:" + string);

}
}
}


Server端代码

/**
* 控制台输入信息,聊天小程序
*
* @author xuyi3
* @2016年7月18日 @上午10:24:56
* @Server2
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class Server2 {
public static void main(String[] args) throws Exception {

// 新建服务端ServerSocket对象,必须要指定监听端口
ServerSocket serverSocket = new ServerSocket(9999);
// 阻塞监听...
System.out.println("阻塞监听");
// 监听端口创建一个新的连接
Socket socket = serverSocket.accept();

// 通过Socket对象获得连接的输入流
InputStream in = socket.getInputStream();
// 通过Socket对象获得连接的输出流
OutputStream out = socket.getOutputStream();

// 使用更方便的缓冲包装流来操作
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));

// 控制台输入流
Scanner scanner = new Scanner(System.in);

while (true) {

// 读取客户端信息
String string = reader.readLine();
System.out.println("客户端:" + string);

// 输出信息给服务器
System.out.print("服务器:");
String line = null;
line = scanner.nextLine();
writer.write(line);
// 以下两步非常重要否则会出问题,是对方输入流一直阻塞。
writer.newLine();
writer.flush();

}
}
}


基于UDP聊天程序

Client客户端代码

/**
* 基于UDP的聊天程序
*
* @author xuyi3
* @2016年7月18日 @上午10:52:55
* @UdpClient
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class UdpClient {
public static void main(String[] args) throws Exception {

// 数据包Socket对象,该对象既可以发送数据包也可以接收数据包(类似邮局既可以寄件又可以收件)
DatagramSocket datagramSocket = new DatagramSocket(8888);
Scanner scanner = new Scanner(System.in);
while (true) {

// 发送数据
String line = scanner.nextLine();
// 数据包包裹对象,该对象用来承载数据信息(类似寄件过程中的包裹,发送数据包里面通常会包含要发送目标地址信息、数据大小等)
DatagramPacket sendPacket = new DatagramPacket(line.getBytes(), 0, line.length(),
InetAddress.getLocalHost(), 8889);
datagramSocket.send(sendPacket);

// 接收数据
byte[] tem = new byte[1024];
//接收数据包通常只需要指定数据大小即可
DatagramPacket receivePacket = new DatagramPacket(tem, tem.length);
datagramSocket.receive(receivePacket);
byte[] data = receivePacket.getData();
System.out.println("服务器:" + new String(data, 0, data.length));

}
}
}


Server端代码

/**
* 基于UDP的聊天程序
*
* @author xuyi3
* @2016年7月18日 @上午11:08:49
* @UdpServer
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class UdpServer {
public static void main(String[] args) throws Exception {
// 数据包Socket对象,该对象既可以发送数据包也可以接收数据包(类似邮局既可以寄件又可以收件)
DatagramSocket datagramSocket = new DatagramSocket(8889);
Scanner scanner = new Scanner(System.in);

while (true) {
// 接收数据
byte[] tem = new byte[1024];
// 接收数据包通常只需要指定数据大小即可
DatagramPacket receivePacket = new DatagramPacket(tem, tem.length);
datagramSocket.receive(receivePacket);
byte[] data = receivePacket.getData();
System.out.println("客户端:" + new String(data, 0, data.length));

// 发送数据
String line = scanner.nextLine();
// 数据包包裹对象,该对象用来承载数据信息(类似寄件过程中的包裹,里面通常会包含要发送目标地址信息、数据大小等)
DatagramPacket sendPacket = new DatagramPacket(line.getBytes(), 0, line.length(),
InetAddress.getLocalHost(), 8888);
datagramSocket.send(sendPacket);

}

}

}


基于tcp的网络文件传输

Client客户端代码

/**
* 基于TCP实现文件上传和下载功能
*
* @author xuyi3
* @2016年7月18日 @上午11:28:51
* @UploadClient
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class UploadClient {

public static void main(String[] args) throws Exception {

// 客户端新建Socket对象,必须制定主机地址和端口
Socket socket = new Socket("192.168.1.187", 9999);

// 通过Socket对象获得连接的输出流
OutputStream out = socket.getOutputStream();

// 要上传的文件路径
FileInputStream fileInputStream = new FileInputStream(new File("e:/git.png"));

byte[] bytes = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
fileInputStream.close();
out.flush();
out.close();
}
}


Server端代码

/**
*
* 基于TCP实现文件上传和下载功能
*
* @author xuyi3
* @2016年7月18日 @下午1:27:02
* @UploadServer
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class UploadServer {

public static void main(String[] args) throws Exception {

// 新建服务端ServerSocket对象,必须要指定监听端口
ServerSocket serverSocket = new ServerSocket(9999);
// 阻塞监听...
System.out.println("阻塞监听");
// 监听端口创建一个新的连接
Socket socket = serverSocket.accept();

// 通过Socket对象获得连接的输入流
InputStream in = socket.getInputStream();

// 指定要下载的文件保存路径
FileOutputStream fileOutputStream = new FileOutputStream(new File("e:/gitcopy.png"));

byte[] bytes = new byte[1024];
int len = 0;
while ((len = in.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, len);
}

fileOutputStream.close();
System.out.println("传输完成");

}

}


多客户端聊天

多客户端聊天程序,客户端代码不变,服务器端代码需要调整。思路:每连接过来一个客户端就新建一个线程单独给予处理这个客户端,
因此要抽取公共代码到线程类里面。


ServerThread线程类代码

public class ServerThread implements Runnable {

private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}

@Override
public void run() {

try {

// 通过Socket对象获得连接的输入流
InputStream in = socket.getInputStream();
// 通过Socket对象获得连接的输出流
OutputStream out = socket.getOutputStream();

// 使用更方便的缓冲包装流来操作
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));

// 控制台输入流
Scanner scanner = new Scanner(System.in);

while (true) {

// 读取客户端信息
String string = reader.readLine();
System.out.println("客户端:" + string);

// 输出信息给服务器
System.out.print("服务器:");
String line = null;
line = scanner.nextLine();
writer.write(line);
// 以下两步非常重要否则会出问题,是对方输入流一直阻塞。
writer.newLine();
writer.flush();

}
} catch (Exception e) {
e.printStackTrace();
}

}

}


Server端代码

/**
* 控制台输入信息,聊天小程序<br>
* 多客户端聊天,使用多线程为每个客户端新建一个独立线程来使用<br>
*
* 客户端代码不用修改,只需要修改服务器端代码即可<br>
*
*
* @author xuyi3
* @2016年7月18日 @上午10:24:56
* @Server2
* @功能说明:<br>
* @春风十里不如你
* @备注
*/
public class Server3 {
public static void main(String[] args) throws Exception {

// 新建服务端ServerSocket对象,必须要指定监听端口
ServerSocket serverSocket = new ServerSocket(9999);

while (true) {
// 阻塞监听...
System.out.println("阻塞监听");
// 监听端口创建一个新的连接
Socket socket = serverSocket.accept();

new Thread(new ServerThread(socket)).start();

}

}

}


总结

网络编程的实际用途可能有很多,但是其核心的两种编程模型就是TCP编程模型和UDP编程模型,总体思路都是相同的。


参考

1、http://www.ibm.com/developerworks/cn/education/linux/l-sock/l-sock.html

2、http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html

3、https://en.wikipedia.org/wiki/Network_socket
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息