目录
IP地址(Internet Protocol):唯一标识网络上的每一台计算机
IP地址的组成:32位,由4个8位二进制数组成
IP地址 = 网络地址 +主机地址
网络地址:标识计算机或网络设备所在的网段
主机地址:标识特定主机或网络设备
查看本机的IP地址:ipconfig
测试网络是否通畅:ping 目标IP地址
网络通信协议:为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合
一、Socket
通信链路的端点就被称为“套接字”(英文名Socket
):是提供给应用程序的接口
):是提供给应用程序的接口
Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制
基于TCP协议的Socket编程
基于TCP协议的Socket网络通信:
用来实现双向安全连接网络通信
用来实现双向安全连接网络通信
1、Socket通信模型
进行网络通信时,Socket
需要借助数据流来完成数据的传递工作
需要借助数据流来完成数据的传递工作
2、Socket网络编程一般可以分成如下步骤进行
1、建立连接
2、打开Socket关联的输出入输出流
3、数据流种读写信息
4、关闭所有的数据流和Socket
实例:
建立客户端
public class Client {
public static void main(String[] args) {
try {
//建立客户端socket连接,指定服务器的位置为本机以及端口为8080
Socket socket = new Socket("127.0.0.1",8080);
System.out.println("****************客户端已启动***************");
//打开输出流
OutputStream os = socket.getOutputStream();
//打开输入流
InputStream is = socket.getInputStream();
//发送客户端信息,即向输出流写入信息
String info = "用户名:tom;用户密码:123456";
os.write(info.getBytes(StandardCharsets.UTF_8));
socket.shutdownOutput();
//接收服务器端的响应,即从输入流读取信息
String replay = null;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((replay = br.readLine()) != null){
System.out.println("我是客户端,服务器端响应为:" + replay);
}
//关闭资源
os.flush();
os.close();
is.close();
br.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
建立服务端
public class Server {
public static void main(String[] args) {
try {
//建立客户端serverSocket连接,指定服务器的位置为本机以及端口为8080
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("****************服务端已启动***************");
//使用accept()方法等待客户端发起通信
Socket socket = serverSocket.accept();
//打开输入流
InputStream is = socket.getInputStream();
//打开输出流
OutputStream os = socket.getOutputStream();
//获取客户信息,从输入流读取信息
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine()) != null){
System.out.println("我是服务器,客户登录信息为:" + info);
}
//给客户端一个响应
String reply = "欢迎您,登录成功!";
//
os.write(reply.getBytes(StandardCharsets.UTF_8));
//关闭资源
os.flush();
os.close();
is.close();
br.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、Socket中实现对象的传递
传递对象信息需要序列化
方法:
ObjectOutputStream oos = new ObjectOutputStream(…);
oos.writeObject(…);
ObjectInputStream ois = new ObjectInputStream(…);
Object = ois.readObject();
实例:
创建用户类
public class User implements Serializable {
private String name;
private String password;
private String gender;
private String phone;
private String message;
//.......有参,无参
//.......set/get/方法
}
创建服务端
public class ServerSocketTcp {
public static void main(String[] args) {
try {
//建立客户端serverSocket连接,指定服务器的位置为本机以及端口为8080
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("*******************服务器端已启动*****************");
//使用accept()方法等待客户端发起通信
Socket socket = serverSocket.accept();
//反序列化
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
//打开输出流
OutputStream os = socket.getOutputStream();
//获取客户信息,从输入流读取信息
User user = (User)ois.readObject();
String response = "";
if("admin".equals(user.getName()) && "123456".equals(user.getPassword())){
System.out.println("客户端登录成功");
System.out.println("客户端的登录信息是:" + user);
System.out.println("客户端发送的消息:" + user.getMessage());
response = "客户端登录成功!允许访问服务器";
}else{
response = "登录失败!用户名或密码错误!";
}
//给客户端一个响应,即向输出流中写入信息
os.write(response.getBytes(StandardCharsets.UTF_8));
//关闭资源
os.flush();
os.close();
ois.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
创建客户端
public class ClientSocketTcp {
public static void main(String[] args) {
try {
//建立客户端socket连接,指定服务器的位置为本机以及端口为8080
Socket socket = new Socket("127.0.0.1",8080);
System.out.println("******************客户端已连接********************");
//打开输出流
OutputStream os = socket.getOutputStream();
//对象序列化
ObjectOutputStream oos = new ObjectOutputStream(os);
//
BufferedReader bw = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//String request = "你好啊,服务器端,我这里是客户端";
User user = new User("admin","123456","男","18037678296","你好,客户端申请登录");
//向对象输出流中写入信息
oos.writeObject(user);
oos.flush();
//接收服务器端的响应,即从输入流读取信息
String line = null;
String info = "";
while ((line=bw.readLine())!=null){
info += line;
}
System.out.println("客户端收到的信息:" + info);
bw.close();
oos.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
System.err.println("客户端连接到服务器端失败!");
}
}
}
4、多线程处理多请求
创建用户类
public class User1 implements Serializable {
private String name;
private String password;
private String gender;
private String phone;
private String message;
//.......有参,无参
//.......set/get/方法
}
将服务端接收回复内容写入线程中
public class LoginThread extends Thread{
private Socket socket;
public LoginThread(Socket socket){
this.socket = socket;
}
@Override
public void run(){
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
OutputStream os = socket.getOutputStream();
User user = (User)ois.readObject();
String response = "";
if("admin".equals(user.getName()) && "123456".equals(user.getPassword())){
System.out.println("客户端登录成功");
System.out.println("客户端的登录信息是:" + user);
System.out.println("客户端发送的消息:" + user.getMessage());
response = "客户端登录成功!允许访问服务器";
}else{
response = "登录失败!用户名或密码错误!";
}
os.write(response.getBytes(StandardCharsets.UTF_8));
os.flush();
os.close();
ois.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
创建服务端
public class ServerSocketTcp {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("******************服务端已启动********************");
Socket socket = null;
while (true){
socket = serverSocket.accept();
LoginThread loginThread = new LoginThread(socket);
loginThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建客户端
public class ClientSocketTcp {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1",8080);
System.out.println("******************客户端已连接********************");
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
BufferedReader bw = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//String request = "你好啊,服务器端,我这里是客户端";
User user = new User("root","123456","男","18037678296","你好,客户端申请登录");
oos.writeObject(user);
oos.flush();
String line = null;
String info = "";
while ((line=bw.readLine())!=null){
info += line;
}
System.out.println("客户端收到的信息:" + info);
bw.close();
oos.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
System.err.println("客户端连接到服务器端失败!");
}
}
}
可以创建多个客户端,但端口要与服务端相同,要不然会报错
TCP | UDP | |
是否连接 | 面向连接 | 面向非连接 |
传输可靠性 | 可靠 | 不可靠 |
速度 | 慢 | 快 |
二、基于UDP协议的Socket编程
1、基于UDP协议的Socket网络编程步骤
1、利用DatagramPacket 对象封装数据包
2、利用 DatagramSocket 发送数据包
3、利用DatagramSocket接收数据包
4、利用DatagramPacket 处理数据包
实例:
创建服务端
public class ServerSocketUdp {
public static void main(String[] args) {
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
try {
DatagramSocket socket = new DatagramSocket(9090);
socket.receive(dp);
String info = new String(bytes,0,bytes.length);
System.out.println("客户端:" + info);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建客户端
public class ClinetSocketUdp {
public static void main(String[] args) {
String info = "你好,这里是客户端!";
byte[] bytes = info.getBytes(StandardCharsets.UTF_8);
try {
InetAddress inetAddress = InetAddress.getByName("localhost");
DatagramSocket socket = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(bytes,bytes.length,inetAddress,9090);
socket.send(dp);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/93372.html