心得感悟
日常懵逼,但是多看几次,多写几次就好了。感觉编程最难的地方就是我们对程序很陌生,怕陌生的代码,还是要多练,编程有些东西真的是只可意会不可言传。觉得今天学的socket很有意思,因为它让程序不再是孤单的自己,它可以连接外面的世界,莫名感觉它很伟大。
内容简概
- 一、网络编程介绍
- 二、Socket介绍
- 三、用Socket实现数据传输
- 四、运行效果
具体内容
一、网络编程介绍
1. 什么是网络编程?
网络编程的本质是两个设备之间的数据交换
,即网络通信。通常,设备指的是计算机。
2. 网络编程的模型
在网络通信中主要有两种通信模式,一种是B/S结构
(Browser/Server,浏览器/服务器模式),另一种是C/S结构
(Client/Server,服务器/客户机模式)。B/S模式常见于我们使用的浏览器,我们点击进入一个网页,服务器就返回给我们信息。C/S模式常见于我们的端游、应用软件,我们直接在上面操作,不会访问到其他地方。在这里,我们着重讲C/S模式
。
3. IP地址和域名
IP地址
是分配给用户上网使用的网际协议的设备的数字标签
。在现实生活中,写信需要知道对方的地址,打电话需要知道对方的手机号码。互联网中也一样,网络中的数据传输就是通过获取每个设备的IP地址实现的。由于IP地址不便于阅读,于是某个聪明的人就想到给它取一个名字,这个名字就是域名。比如baidu.com就是一个域名。
如何查看自己电脑的IP地址呢?
用win+R键
打开搜索框,输入cmd
进入命令提示符,最后输入ipconfig
按下回车,就可以看到自己电脑的IP地址啦。
IP地址
4. 数据传输协议TCP/UDP
TCP(传输控制协议):面向连接的 安全的
UDP(用户数据报协议):面向无连接的 不安全 但速度快
它们之间有什么关系呢?用一张图告诉你。
5. IP地址和端口号
端口号:每个应用程序对应一个端口号,通过类似门牌号的端口号,客户端才能真正的访问到该服务器。使用端口号,可以找到一台设备上唯一的一个程序。
所以如果需要和某台计算机建立连接的话,只需要知道IP地址或域名即可,但是如果想和该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号。
二、Socket介绍
1. 什么是Socket?
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据
,可对其进行像对文件一样的打开、读写和关闭等操作。 简单来说是IP地址与端口的结合协议
。Socket = (IP地址:端口号)
。套接字的表示方法是点分十进制的IP地址后面写上端口号,中间用冒号或逗号
隔开。
那socket和IP/TCP有什么关系吗?
套接字可以看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。因此,两个应用程序之间的数据传输要通过套接字来完成
。
2. Socket通信模式
Socket可以实现网络间的数据传输
,接下来我就将具体介绍编程中如何使用Socket。
三、用Socket实现数据传输
1. Socket——客户端向服务器端发送固定信息
下面这个例子是实现客户端向服务器端发送默认的信息。先简单了解一下服务器端和客户端的搭建。
127.0.0.1
是通用的本机IP地址。
端口号
一般用到的是1到65535,其中0不使用。一般的应用程序使用1024到4999用来通讯。5000以后的用来用户自定义端口。所以我们自己编程时尽量使用5000后的,避免端口被占用。
// 模拟客户端
class Client {
public static void main(String[] args) throws IOException {
// 1.创建用于通信的socket
// 指明和谁通信:IP地址 端口号
Socket socket = new Socket("127.0.0.1",8989);
// 接收服务器端的数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 读取服务器端发来的数据
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
// 客户端向服务器端发送数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("你好啊");
socket.shutdownOutput();
}
}
// 模拟服务器端
class Server {
public static void main(String[] args) throws IOException {
// 1.创建服务器端的ServerSocket
ServerSocket ss = new ServerSocket(8989);
// 2.获取连接的客户端的socket
Socket clientSocket = ss.accept();
// 3.向客户端发送数据
// 法一:BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
//法二:
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
ps.println("登陆成功");
// 输出完毕
clientSocket.shutdownOutput();
// 4.接收客户端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
2. Socket——服务器端向客户端发送可变信息
下面实现从终端向服务器端⼿动输⼊信息,服务器端会把输⼊的内容发送给客户端,可以⼀直发。
class MyClient {
public static void main(String[] args){
// 链接服务器端的socket
Socket socket = null;
try {
socket = new Socket("127.0.0.1",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){
// 创建ServerSocket
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();
}
}
}
3. Socket——客户端向服务器端上传图⽚
下面实现客户端向服务器端上传图⽚。建议使用jpg格式的图片。注意!音频图片一般都采用字节流传输,故输入输出时都需要用字节流,而不能用字符流
。
class Client{
public static void main(String[] args) throws IOException {
// 连接服务器端 获取socket
Socket socket = new Socket("127.0.0.1",8080);
// 创建服务器端对应的输入流 用于接收服务器端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
// 向服务器端发送文件(图片)
// 1.将文件写入到内存里
String path = "C:/Users/ASUS/Pictures/有空画画/20131108104858_uGFa5.jpeg";
FileInputStream fis = new FileInputStream(path);
// 2.创建字节流 outputStream
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[1024];
int len = -1;
while ((len = fis.read(buf)) != -1){
bos.write(buf,0,len);
}
socket.shutdownOutput();
}
}
class Server{
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8080);
// 监听客户端连接
// 当有客户端连接服务器 就可以得到对应的socket对象
// 无则等待
Socket socket = ss.accept();
// 创建客户端对应的输出流 用于向这个客户端发送数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("连接成功 可以发数据了");
// 接收客户端传递过来的图片
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
String path = "F:/homework/java/day1/java/src/main/java/day12/media/1.jpeg";
FileOutputStream fos = new FileOutputStream(path);
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
fos.write(buf,0,len);
}
socket.shutdownOutput();
}
}
四、运行效果
客户端向服务器端发送固定文字
注意!运行时要先开启服务器,再运行客户端。
下面的效果图与上述顺序相同。
服务器端向客户端不断发消息
客户端向服务器端上传图⽚
网友评论