标签:port 机器名 写入文本 address 地理位置 user 输入输出 通信协议 设备
IP地址:是网络中设备的唯一标识
IP地址分为两大类
常用命令:
特殊IP地址:
为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用
InetAddress:此类表示Internet协议(IP)地址
方法名 | 说明 |
---|---|
static InetAddress getByName(String host) | 确定主机名称的IP地址。主机名可以是机器名称,也可以是IP地址 |
String getHostName() | 获取此IP地址的主机名 |
String getHostAddress() | 返回文本显示中的IP地址字符串 |
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
// 可以是主机名,也可以是IP地址的字符串
// InetAddress yuki = InetAddress.getByName("Yuki");
InetAddress yuki = InetAddress.getByName("192.168.1.63");
String name = yuki.getHostName();
String address = yuki.getHostAddress();
System.out.println("这台电脑的名字:" + name);
System.out.println("这台电脑的IP地址:" + address);
}
}
端口:设备上应用程序的唯一标识
端口号:用两个字节表示的整数,它的取值范围是0-65535。其中,0-1023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败
协议:计算机网络中,连接和通信的规则被称为网络通信协议
UDP协议
用户数据报协议(User Datagram Protocol)
UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另一台计算机发送数据时,发送端不会确认接收数据端是否存在,就会发出数据,同样接收端再收到数据时,也不会向发送端反馈是否收到数据
由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频,视频和普通数据的传输
例如视频会议通常采用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议
TCP协议
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
Java提供了DatagramSocket类作为基于UDP协议的Socket
发送数据的步骤
创建发送端的Socket对象(DatagramSocket)
? DatagramSocket()
创建数据,并把数据打包
? DatagramPacket(byte[] buf, int length, InetAddress address, int port)
调用DatagramSocket对象的方法发送数据
? void send(DatagramPacket p)
关闭发送端
? void close()
import java.io.IOException;
import java.net.*;
/*
发送数据的步骤
1. 创建发送端的Socket对象(DatagramSocket)
2. 创建数据,并把数据打包
3. 调用DatagramSocket对象的方法发送数据
4. 关闭发送端
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
// 创建发送端的Socket对象(DatagramSocket)
// DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。
DatagramSocket ds = new DatagramSocket();
// 创建数据,并把数据打包
// DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// 构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
byte[] bytes = "hello world love you".getBytes();
DatagramPacket dp = new DatagramPacket(bytes,
bytes.length,
InetAddress.getByName("Yuki"),
9000);
// 调用DatagramSocket对象的方法发送数据
// void send(DatagramPacket p) 从此套接字发送数据报包。
ds.send(dp);
// 关闭发送端
// void close() 关闭此数据报套接字。
ds.close();
}
}
接收数据的步骤
创建接收端的Socket对象(DatagramSocket)
? DatagramSocket(int port)
创建一个数据包,用于接收数据
? DatagramPacket(byte[] buf,int length)
调用DatagramSocket对象的方法接收数据
? void receive(DatagramPacket p)
解析数据包,并把数据在控制台打印
? byte[] getData()
? int getLength()
关闭接收端
? void close()
import java.io.IOException;
import java.net.*;
/*
接收数据的步骤
1. 创建接收端的Socket对象(DatagramSocket)
2. 创建一个数据包,用于接收数据
3. 调用DatagramSocket对象的方法接收数据
4. 解析数据包,并把数据在控制台打印
5. 关闭接收端
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象(DatagramSocket)
// DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket ds = new DatagramSocket(9000);
// 创建一个数据包,用于接收数据
// DatagramPacket(byte[] buf, int length)
// 构造一个DatagramPacket用于接收长度为length数据包
byte[] bytes1 = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes1, bytes1.length);
// 调用DatagramSocket对象的方法接收数据
ds.receive(dp);
// 解析数据包,并把数据在控制台打印
// byte[] getData() 返回数据缓冲区
// int getLength() 返回要发送的数据的长度或接收到的数据的长度
String s = new String(dp.getData(),0,dp.getLength());
// 关闭接收端
ds.close();
}
}
按照下面要求实现程序
// 发送端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
按照下面要求实现程序
- UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
- UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String next;
try {
while ((next = br.readLine())!=null) {
if(next.equals("886")){
break;
}
DatagramPacket dp = new DatagramPacket(
next.getBytes(),next.length(),InetAddress.getByName("Yuki"), 9000);
ds.send(dp);
}
} finally {
ds.close();
}
}
}
// 接收端代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(9000);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
try {
while (true) {
ds.receive(dp);
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("接收数据为:" + s);
}
} finally {
ds.close();
}
}
}
/*
要先打开接收端,再打开发送端
*/
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信
Java对基于TCP协议的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信
Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
发送数据的步骤
创建客户端的Socket对象(Socket)
? Socket(String host, int port)
获取输出流,写数据
? OutputStream getOutputStream()
释放资源
? void close();
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/*
发送数据的步骤
1. 创建客户端的Socket对象(Socket)
2. 获取输出流,写数据
3. 释放资源
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端的Socket对象(Socket)
// Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
// 可以写自己或者通网络下别人的IP地址
Socket socket = new Socket("192.168.1.63",9000);
// 获取输出流,写数据
// OutputStream getOutputStream() 返回此套接字的输出流
OutputStream os = socket.getOutputStream();
os.write("hello world".getBytes());
// 释放资源
socket.close();
}
}
/*
因为只写了客户端的发送数据,并没有与服务器连接,所以单运行这段代码会报未连接异常
*/
接收数据的步骤
创建服务器端的Socket对象(ServerSocket)
? ServerSocket(int port)
监听客户端的连接,返回一个Socket对象
? Socket accept()
获取输入流,读数据,并把数据显示在控制台上
? InputStream getInputStream()
释放资源
? void close()
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
接收数据的步骤
1. 创建服务器端的Socket对象(ServerSocket)
2. 获取输入流,读数据,并把数据显示在控制台上
3. 释放资源
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器端的Socket对象(ServerSocket)
// ServerSocket(int port) 创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(9000);
// Socket accept() 侦听要连接到此套接字并接受它
Socket accept = ss.accept();
// 获取输入流,读数据,并把数据显示在控制台上
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
String s = new String(bytes, 0, len);
System.out.println("数据是:" + s);
// 释放资源
accept.close();
ss.close();
}
}
/*
先打开服务器,后打开客户端
*/
练习1
// 客户端代码
import java.io.*;
import java.net.Socket;
/*
练习1
- 客户端:发送数据,接收服务器反馈
- 服务器:接收数据,给出反馈
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建Socket对象,指定IP和端口
Socket s = new Socket("192.168.1.63", 9000);
// 创建输入输出流,用于发送和接收数据
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
try {
while ((line = br.readLine()) != null) {
os.write(line.getBytes());
if (line.equals("886")) {
break;
}
byte[] bytes = new byte[1024];
int len = is.read(bytes);
String data = new String(bytes, 0, len);
System.out.println("从服务器反馈的数据:" + data);
}
} finally {
// 释放资源
// 如果Socket那么根据socket创建的输入输出流也被释放
s.close();
}
}
}
// 服务器端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建ServerSocket对象,指定端口
ServerSocket ss = new ServerSocket(9000);
// 通过ss对象获取目标Socket
Socket accept = ss.accept();
// 创建输入输出流用于发送、接收对象
InputStream is = accept.getInputStream();
OutputStream os = null;
try {
while (true) {
byte[] bytes = new byte[1024];
int len = is.read(bytes);
String data = new String(bytes, 0, len);
System.out.println("接收到的数据:" + data);
if(data.equals("886")){
break;
}
os = accept.getOutputStream();
os.write("收到,over".getBytes());
}
} finally {
// 释放资源
ss.close();
}
}
}
练习2
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建Socket对象,指定IP和端口
Socket s = new Socket("192.168.1.63", 9000);
// 创建输入输出流,用于发送和接收数据
BufferedReader br = new BufferedReader(new FileReader(
"test\\src\\com\\itcast\\unit12\\test6\\ClientData.txt"));
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 自定义结束标记
// bw.write("-1");
// bw.newLine();
// bw.flush();
// void shutdownOutput() 禁用此套接字的输出流
s.shutdownOutput();
InputStream is = s.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
String data = new String(bytes,0,len);
System.out.println("服务器:"+data);
} finally {
// 释放资源
// 如果Socket那么根据socket创建的输入输出流也被释放
br.close();
s.close();
}
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建ServerSocket对象,指定端口
ServerSocket ss = new ServerSocket(9000);
// 通过ss对象获取目标Socket
Socket accept = ss.accept();
// 创建输入输出流用于发送、接收对象
OutputStream os = accept.getOutputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(accept.getInputStream()));
BufferedWriter writer = new BufferedWriter(new FileWriter(
"test\\src\\com\\itcast\\unit12\\test6\\ServerData.txt"));
String data;
try {
while ((data = br.readLine())!=null) {
// if (data.equals("-1")) {
// break;
// }
writer.write(data);
writer.newLine();
writer.flush();
System.out.println("接收到的数据:" + data);
}
os.write("接收完毕".getBytes());
} finally {
// 释放资源
writer.close();
ss.close();
}
}
}
练习3
// 客户端代码
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 写自己的IP地址
Socket s = new Socket("192.168.1.63", 9000);
BufferedReader br = new BufferedReader(new FileReader(
"test\\src\\com\\itcast\\unit12\\test7\\ClientData.txt"));
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
s.shutdownOutput();
BufferedReader brClient = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("服务器:"+data);
} finally {
// 释放资源
br.close();
s.close();
}
}
}
// 服务器代码
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9000);
while (true) {
Socket s = ss.accept();
new Thread(new ServerThread(s)).start();
}
}
}
// 服务器线程代码
import java.io.*;
import java.net.Socket;
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
// String path = "test\\src\\com\\itcast\\unit12\\test7\\ServerData.txt";
// BufferedWriter bw = new BufferedWriter(new FileWriter(path));
// 解决名字冲突问题
int count = 0;
String path;
path = "test\\src\\com\\itcast\\unit12\\test7\\ServerData["+count+"].txt";
File file = new File(path);
while (file.exists()) {
count++;
file = new File(path);
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
BufferedWriter bwServer = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
bwServer.write("服务器端接收完毕");
bwServer.newLine();
bwServer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
标签:port 机器名 写入文本 address 地理位置 user 输入输出 通信协议 设备
原文地址:https://www.cnblogs.com/clevergirl/p/11393515.html