Socket 网络编程
目的
了解什么是网络编程
网络编程:在两台不同的计算机之间传递数据
1.QQ聊天
2.打开网易app 刷新界面 就有数据
3.打开浏览器 网页 www.baidu.com
客户端:手机APP 浏览器 桌面QQ
服务器端:存储、处理数据
URL:统一的资源定位
http/https :传输协议 TCP/ IP
www.baidu.com:域名 表示一台网络中的电脑
IPv4 IPv6 地址 : 唯一标识一网络中的计算机
32位:四个部分 每个部分是8个字节
170.20.10.15DNS服务器:域名解析
将www.baidu.com类型的域名解析为对应的IP地址search 对应的后台程序文件 PHP java jsp
? 表示运行这个程序需要传递的参数
code=android code是服务器端规定的字段
& 如果有多个参数 使用&符号链接
IP地址 找到这台电脑 唯一标识一台电脑
端口号:找到这台电脑上的某一个程序 唯一标识电脑上的某一个进程(程序)
数据传输:TCP/IP协议
TCP:面向链接的 安全的
UDP:面向无链接的 不安全 但快
网络中的数据传输:Socket实现->套接字
Socket:客服端
ServerSocket:服务器端
读取数据:服务器读取 客户端读取
BufferedReader -> InputStreamReader -> socket.getInputStream();
读取终端
BufferedReader -> InputStreamReader -> System.in输出:客户端输出 服务器端输出
BufferedWriter -> OutputStreamWriter -> socket.getOutputStream();
技术
1.实现客户端和服务器端传递数据
2.实现服务器端手动输入,将输入的内容发送给客户端
3.实现客户端向服务器端上传图片
4.使用多线程对聊
5.实现群聊
技术实现
- 实现客户端和服务器端传递数据
注意端口号必须相同 先运行Server 再运行Client
// 模拟客户端
class Client{
public static void main(String[] args) throws IOException {
// 1.创建用于通信的socket
// 指明和谁通信:IP地址 端口号
Socket socket = new Socket("10.129.28.234",6767);
// 接收服务器端的数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// // 向服务器端发送数据
//
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// bw.write("thank you very much");
// 读取服务器端发来的数据
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
// 客户端向服务器端发送数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("你好啊");
socket.shutdownInput();
}
}
// 模拟服务器端
class Server{
public static void main(String[] args) throws IOException {
// 1.创建服务器端的serverSocket
ServerSocket ss = new ServerSocket(6767);
// 2.获取链接的客户端的socket
Socket clientSocket = ss.accept();
// 3.向客户端发送数据
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
ps.println("登录成功");
// 输出完毕
clientSocket.shutdownInput();
// 读取客户端信息
// BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// String line = null;
// while ((line = br.readLine()) != null) {
// System.out.println(line);
// }
//4.接收客户端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
- 实现服务器端手动输入,将输入的内容发送给客户端
可以一直发
class MyClient{
public static void main(String[] args) throws IOException {
Socket socket = null;
// 连接服务器端的socket
try {
socket = new Socket("10.129.28.234",8888);
// 接收服务器端的信息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络出错,请重新登录"); }finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class MyServer{
public static void main(String[] args){
try( ServerSocket ss = new ServerSocket(8888)) {
// 监听客户端
Socket socket = ss.accept();
// 从终端接收数据
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
// 获取向客户端输出数据的输出流
PrintStream ps = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine())!= null){
// 发送给客户端
ps.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 实现客户端向服务器端上传图片
class Client{
public static void main(String[] args) throws IOException {
// 连接服务器端 获取 socket
Socket socket = new Socket("10.129.28.234",1111);
// 创建服务器端对应的输入流 用于接收服务器端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
// 向服务器端发送图片
// 1.将文件写入到内存里
String path = "C:\\Users\\Administrator\\Desktop\\Android\\firstExperience\\java\\src\\main\\java\\day8\\1.jpg";
FileInputStream fis = new FileInputStream(path);
// 2.创建字节流
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
// 3.将文件的内容一点一点的传输到服务器
byte[] buf = new byte[1024];
int len = -1;
while ((len = fis.read(buf))!= -1){
bos.write(buf,0,len);
}
}
}
class Server{
public static void main(String[] args) throws IOException {
// 创建服务器端的ServerSocket
ServerSocket ss = new ServerSocket(1111);
// 监听客户端连接
// 当前有客户端来连接这个服务器 就可以得到对应的socket
// 当没有客户端来连接 服务器一直在这里等待
Socket socket = ss.accept();
// 创建客户端对应的输出流 用于向这个客户端发送数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("连接成功 可以发数据了");
// 接收客户端传递过来的图片
// 文件对应的输出流
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
String path = "C:\\Users\\Administrator\\Desktop\\Android\\firstExperience\\java\\src\\main\\java\\day12\\medio\\2.jpg";
FileOutputStream fos = new FileOutputStream(path);
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
fos.write(buf,0,len);
}
}
}
- 使用多线程实现对聊
class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.28.234",6789);
// 主线程处理终端输入 发送给服务器端
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
PrintStream ps = new PrintStream(socket.getOutputStream());
// 用一个子线程处理服务器端数据
new Thread(new ClientThread(socket)).start();
String line = null;
while ((line = keyin.readLine())!=null){
ps.println(line);
}
}
}
/**
* 创建一个子线程处理客户端接收服务器端的数据
*/
class ClientThread implements Runnable{
private Socket socket;
// 保存socket对象
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
// 获取服务器端的输入流对象
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络出错 请重新登录");
System.exit(-1);
}finally {
if(br != null){
try {
br.close();
if (socket != null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(6789);
Socket socket = ss.accept();
// 创建子线程 处理客户端输入信息
new ServerThread(socket).start();
// 终端输入流对象
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
// 客户端的输出流
PrintStream ps = new PrintStream(socket.getOutputStream());
// 读取终端的输入 将输入输出给客户端
String line = null;
while ((line = keyin.readLine()) != null){
ps.println(line);
}
}
}
/**
* 创建一个子线程处理服务器端接收客户端的数据
*/
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine())!= null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络异常 请重新登录");
System.exit(-1);
}finally {
try {
if (br != null){
br.close();
}
if (socket != null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 实现群聊
class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.28.234",7657);
// 主线程处理终端输入 发送给服务器端
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
PrintStream ps = new PrintStream(socket.getOutputStream());
// 用一个子线程处理服务器端数据
new Thread(new ClientThread(socket)).start();
String line = null;
while ((line = keyin.readLine())!=null){
ps.println(line);
}
}
}
class Client1 {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.28.234",7657);
// 主线程处理终端输入 发送给服务器端
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
PrintStream ps = new PrintStream(socket.getOutputStream());
// 用一个子线程处理服务器端数据
new Thread(new ClientThread(socket)).start();
String line = null;
while ((line = keyin.readLine())!=null){
ps.println(line);
}
}
}
class Server{
// 保存每一个连接过来的socket对象
public static ArrayList<Socket> sockets = new ArrayList<>();
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(7657);
// 不停地等待客户端来连接
while (true){
Socket socket = ss.accept();
// 当有客户端连接过来了 就保存
sockets.add(socket);
// 开启一个线程处理每个客户端的输入
new ServerThread(socket).start();
}
}
}
class ClientThread implements Runnable{
private Socket socket;
// 保存socket对象
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
// 获取服务器端的输入流对象
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络出错 请重新登录");
System.exit(-1);
}finally {
if(br != null){
try {
br.close();
if (socket != null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine())!= null){
// 群发消息
// 遍历Server维护的数组
for(Socket s:Server.sockets){
// 向socket对应的客户端发送消息
PrintStream ps = new PrintStream(s.getOutputStream());
ps.println(line);
}
}
} catch (IOException e) {
System.out.println("网络异常 请重新登录");
System.exit(-1);
}finally {
try {
if (br != null){
br.close();
}
if (socket != null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
心得
今天学习网络,其实在上课期间我特别懵,就是一直在跟着敲,但是却没有搞懂。感觉挺难的,不过当晚上看视频的时候,很多地方都明白了,感觉也不是那么难。这样我就能更好学习明天的知识了。