网络:
点(PC)与线(线路)的连接,构成网络
计算机网络
不同区域计算机,通过线路连接,实现数据传递,资源共享。
网络编程
数据传输,资源共享的具体实现
网络编程三要素:IP / Port / 协议(TCP/UDP)
TCP协议:transmission control protocol 传输控制协议。
面向连接、可靠、基于字节流,数据大小无限制。
建立连接,三次握手,断开连接四次挥手。
UDP: user datagram protocol用户数据报协议
无连接,传输层协议,提供面向事务简单,不可靠信息传送,每个包64KB
IP协议: internet protocol address 互联网协议地址
分配给互联网设备的唯一标识 (数字标签)
Port: 通信程序的唯一标识。不要超过65535
InetAddress byName1 = InetAddress.getByName("www.baidu.com");
InetAddress[] byName = InetAddress.getAllByName("www.baidu.com");//域名绑定的多个IP
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(byName1);
System.out.println(Arrays.toString(byName));
System.out.println(localHost);
1.发送文本到服务器
先启动server,再启动client. :
/**
* @author Mr.Gao
* @version 1.0
* @date 2021/4/12 23:37
*/
public class Server { //先启动server,再启动client
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9527);
Socket socket = serverSocket.accept(); //阻塞方法1
System.out.println("已经建立连接");
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int len = is.read(b); //阻塞方法2
System.out.println(Arrays.toString(b)); //有值的数组,里面是整数值
System.out.println(new String(b,0,len)); //把数组中整数值部分,转化为字符串
System.out.println(len); //整数 数据长度
IOUtils.closeAll(is,socket,serverSocket);
}
}
/**
* @author Mr.Gao
* @version 1.0
* @date 2021/4/12 23:42
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9527);
System.out.println("客户端与服务器建立了连接");
OutputStream os = socket.getOutputStream();
os.write("向服务器发送的数据".getBytes());
IOUtils.closeAll(os,socket);
}
}
public class IOUtils {
public static void closeAll(Closeable... cs){
for (Closeable c : cs) {
if (c!=null){
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
优化上面的字符流代码:
Socket socket = new Socket("127.0.0.1", 9527);
System.out.println("客户端与服务器建立了连接");
OutputStream os = socket.getOutputStream();
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
bw.write("向服务器发送的数据");
bw.newLine();
bw.flush();
IOUtils.closeAll(os,bw,socket); //先关小,再关大。
ServerSocket serverSocket = new ServerSocket(9527);
Socket socket = serverSocket.accept(); //阻塞方法1
System.out.println("已经建立连接");
InputStream is = socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String msg = br.readLine();
System.out.println(msg);
IOUtils.closeAll(is,br,socket,serverSocket);
2.发送文件给服务器:
Socket socket = new Socket("127.0.0.1", 10086);
//获取本地文件,再写入socket管道
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream("a.jpg");//这个是相对于当前项目的路径。
byte[] b = new byte[1024];
int len;
while ((len=fis.read(b))!=-1){
os.write(b,0,len);
}
IOUtils.closeAll(fis,os,socket);
ServerSocket serverSocket = new ServerSocket(10086);
Socket socket = serverSocket.accept();
//先读后写,服务器从socket获取文件,再写入本地。
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("image/c.jpg"); //写文件时,父目录image一定要有,不然报错,报父目录不存在。
byte[] b = new byte[1024];
int len;
while ((len=is.read(b))!=-1){
fos.write(b,0,len);
}
IOUtils.closeAll(fos,is,socket,serverSocket);
3.多个客户端向服务器发送数据:
newLine()和bw.write("\r\n");一个效果,但是newLine()是支持各种操作平台的
ServerSocket serverSocket = new ServerSocket(10086);
int i=0;
while (true){
i++;
Socket socket = serverSocket.accept();
System.out.println("新socket"+i+"产生");
new ServerThread(socket).start();
}
Socket socket = new Socket("127.0.0.1", 10086);
System.out.println("客户要输入数据了");
Scanner sc = new Scanner(System.in);
//可以类似的把socket看作是外存设备
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while (true){
String msg = sc.next(); //也是个阻塞方法。
bw.write(msg);
bw.newLine(); //没有这个换行,怎么就通信不了?
bw.flush();
if (msg.equals("886")){
break;
}
}
IOUtils.closeAll(bw,socket);
/**
* @author Mr.Gao
* @version 1.0
* @date 2021/4/13 11:11
*/
public class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {//跟客户端聊天的socket
BufferedReader br=null;
try {
br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true){
String msg = br.readLine();
System.out.println(msg);
if (msg.equals("886")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("有一个客户端退出");
IOUtils.closeAll(br,socket);
}
}
}
网络模型:
OSI七层模型
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层
TCP/IP四层模型
应用层,传输层,网络层,网络接口层
数据段–数据包–数据帧–比特流