通信Socket
通过URL读取网页内容
1通过URL对象的openStream()方法可以得到指定资源的输入流。
2通过输入流可以读取、访问网络上的数据。
Socket通信实现步骤
1 创建ServerSocekt和Socket
2 打开连接到Socket的输入/输出流
3 按照协议对Socket进行读写操作
4关闭输入输出流、关闭Socket
基于TCP的Socket通信
客户端能够相应,
服务端:
多线程服务器与多客户端通信:
基本实现步骤:
1 服务器端创建ServerSocket,循环调用accept()等待客户端连接
2 客户端创建一个socket并请求和服务端连接
3 服务端接受客户端请求,创建socket与客户建立专线连接
4 建立连接的两个socket在一个单独的线程对话
5 服务器端继续等待新的连接
案例:
服务端:
客户端同上。
多线程的优先级
如果不设置优先级可能会导致运行时速度非常慢,可降低优先级
输入流与输出流的关闭
对于同一个socket,如果关闭了输出流,则与该输出流关联的socket也会被关闭,所以一般不用
关闭流,直接关闭socket即可
1通过URL对象的openStream()方法可以得到指定资源的输入流。
2通过输入流可以读取、访问网络上的数据。
案例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class UrlTest {
public static void main(String[] args) {
try {
URL url = new URL("http://www.baidu.com");
InputStream is = url.openStream();
InputStreamReader isr = new InputStreamReader(is,"utf-8");
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();
while(data != null){
System.out.println(data);
data = br.readLine();
}
br.close();
isr.close();
is.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Socket通信实现步骤
1 创建ServerSocekt和Socket
2 打开连接到Socket的输入/输出流
3 按照协议对Socket进行读写操作
4关闭输入输出流、关闭Socket
基于TCP的Socket通信
客户端能够相应,
服务端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器端即将启动!!");
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String info = null;
while((info = br.readLine()) != null){
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput();
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("欢迎您!!");
pw.flush();
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",8888);
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("用户名:admin;密码:123");
pw.flush();
socket.shutdownOutput();
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();
pw.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
多线程服务器与多客户端通信:
基本实现步骤:
1 服务器端创建ServerSocket,循环调用accept()等待客户端连接
2 客户端创建一个socket并请求和服务端连接
3 服务端接受客户端请求,创建socket与客户建立专线连接
4 建立连接的两个socket在一个单独的线程对话
5 服务器端继续等待新的连接
案例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread{
Socket socket = null;
public ServerThread(Socket socket){
this.socket = socket;
}
public void run(){
InputStream is= null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info = null;
while((info = br.readLine()) != null){
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput();
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("欢迎您!!");
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(pw!= null)
pw.close();
if(os != null)
os.close();
if(br != null)
br.close();
if(isr != null)
isr.close();
if(is != null)
is.close();
if(socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// serverSocket.close();
}
}
服务端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = null;
int count = 0;
System.out.println("服务器端即将启动!!");
while(true){
socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
count++;
System.out.println("客户端连接数量:" + count);
InetAddress address = socket.getInetAddress();
System.out.println("当前客户端的IP:" + address);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端同上。
UDP
DatagramPacket:表示数据报包
DatagramSocket:进行端到端通信的类
基于UDP的Socket编程
服务端:
package com.hpu.lianxi;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPServer {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8800);
byte[] data = new byte[1024];
System.out.println("服务器已经启动,等待客户端发送数据****");
DatagramPacket packet = new DatagramPacket(data,data.length);
socket.receive(packet);
String info = new String(data,0,packet.getLength());
System.out.println("这是服务端,客户端说:" + info);
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "欢迎您!!".getBytes();
DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address,port);
socket.send(packet2);
socket.close();
}
}
客户端:
package com.hpu.lianxi;
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 UDPClient {
public static void main(String[] args) throws IOException {
InetAddress address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "用户名:admin;密码:123".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length,address,port);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address,port);
socket.receive(packet2);
String reply = new String(data2,0,packet2.getLength());
System.out.println("我是客户端,服务器说:" + reply);
socket.close();
}
}
多线程的优先级
如果不设置优先级可能会导致运行时速度非常慢,可降低优先级
输入流与输出流的关闭
对于同一个socket,如果关闭了输出流,则与该输出流关联的socket也会被关闭,所以一般不用
关闭流,直接关闭socket即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理