网络编程
网络编程:
用来实现网络互连的不同计算机上运行的程序间可以进行数据交换
网络模型:
计算机网络之间以何种规则进行通信,就是网络模型研究问题
网络模型一般是指
OSI(Open System Interconnection开放系统互连)七层参考模型
TCP/IP四层参考模型
网络模型7层概述
1、物理层
2、数据链路层
3、网络层
4、传输层
5、会话层
6、表示层
7、应用层
网络编程三要素:
1、IP地址:InetAddress: 网络中设备的标识,不易记忆,可用主机名
2、端口号: 用于标识进程的逻辑地址,不同进程的标识
3、传输协议: 通讯的规则常见协议:TCP,UDP
IP地址:
IP地址就是给每个连接在Internet上的主机分配的一个32bit地址。
1、IP地址的组成
IP地址 = 网络地址+主机地址
A类IP地址:第一段号码为网络地址,剩下的三段号码为本地计算机的号码
B类IP地址:前二段号码为网络地址,剩下的二段号码为本地计算机的号码
C类IP地址:前三段号码为网络地址,剩下的一段号码为本地计算机的号码
2、IP地址分类
A类:1.0.0.1---127.255.255.254
(1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
(2)127.X.X.X是保留地址,用做循环测试用的。
B类:128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。
C类:192.0.0.1---223.255.255.254 192.168.X.X是私有地址
D类:224.0.0.1---239.255.255.254
E类:240.0.0.1---247.255.255.254
特殊地址:
127.0.0.1 回环地址,可用于测试本机的网络是否有问题. ping 127.0.0.1
3、DOS命令
-------------------------------
ipconfig 查看本机IP地址
xxx.xxx.xxx.255 广播地址
hostname 获取主机名
net view 获取局域网中的所有主机名
ipconfig -all 获取本地IP,主机名,MAC地址
arp -a 获取本局域网中的所有IP地址和物理地址
ping -a x.x.x.x 获取x.x.x.x的主机名
nbtstat -a 主机名 获取MAC地址
-------------------------------
InetAddress类:
为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress 供我们使用
此类表示互联网协议 (IP) 地址。
常见功能:
public static InetAddress getByName(String host)
public String getHostAddress()//获取IP
public String getHostName()//获取主机名
getLocalHost();
端口
1、物理端口:网卡口
2、逻辑端口:我们指的就是逻辑端口
a:每个网络程序都会有一个逻辑端口
b:用于标识进程的逻辑地址,不同进程的标识
c:有效端口:0~65535(两个字节),其中0~1023系统使用或保留端口。
协议:
UDP:
将数据源和目的封装成数据包中,不需要建立连接;
每个数据报的大小在限制在64k;
因无连接,是不可靠协议;
不需要建立连接,速度快
TCP:
建立连接,形成传输数据的通道;
在连接中进行大数据量传输;
需要连接所以是可靠协议;
必须建立连接,效率会稍低
Socket通信原理:
Socket套接字:
Socket=IP+端口号,通信的两端都有Socket。
网络通信其实就是Socket间的通信、数据在两个Socket间通过IO传输。
UDP协议发送、接收数据:
1、UDP协议发送数据(DatagramSocket)
- 步骤:
- a: 创建UDP通讯客户端对象(DatagramSocket)
- b: 创建数据报包 public DatagramPacket(byte[] buf, int length, InetAddress address,int port)
- c: 发送 数据
- d: 释放资源
2、UDP协议发送数据(DatagramSocket)
- 步骤:
- a: 创建UDP通讯客户端对象(DatagramSocket)
- b: 创建数据报包 public DatagramPacket(byte[] buf, int length, InetAddress address,int port)
- c: 发送 数据
- d: 释放资源
程序案例:
例:编写程序,通过UDP协议,完成UDP发送端,不断的将键盘录入的数据发送给接收端,
接收端不断的打印出发送端键盘录入的数据,并测试。
package com.task2.cn;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
System.out.println("请输入信息......");
String s=reader.readLine();
if ("oo".equals(s)){
break;
}
byte[] bytes = s.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length,
InetAddress.getByName("192.168.8.41"), 9889);
socket.send(packet);
}
socket.close();
}
}
package com.task2.cn;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9889);
System.out.println("服务器等待中......");
while (true){
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
socket.receive(packet);
byte[] data = packet.getData();
String ip=packet.getAddress().getHostAddress();
String s=new String(data,0,data.length);
System.out.println(ip+"发来消息:"+s);
}
}
}
TCP协议发送、接收数据:
1、TCP协议发送数据(Scoket)
步骤:
- a: 创建TCP通讯协议客户端对象(Socket) // public Socket(String host, int port)
- b: 获取输出流对象
- c: 写数据
- d: 释放资源
2、TCP协议接收数据(ServerSocket)
步骤:
- a: 创建TCP通讯协议服务器端对象(ServerSocket)
- b: 监听客户端
- c: 获取输入流对象
- d: 读取数据
- e: 释放资源
程序案例:
例:编写程序,通过TCP协议,完成客户端键盘录入,服务器端控制台输出。
public class TCPClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("192.168.8.41", 9889);
OutputStream out = socket.getOutputStream();
BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(out));
while (true) {
System.out.println("请输入字符串");
String s = bfr.readLine();
bfw.write(s);
bfw.newLine();
bfw.flush();
}
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9889);
System.out.println("服务器等待中....");
Socket socket = ss.accept();
InputStream in = socket.getInputStream();
BufferedReader bfr = new BufferedReader(new InputStreamReader(in));
while (true) {
String s = bfr.readLine();
System.out.println(s);
}
}
}
程序小练习:
1、多线程版本的聊天室程序
public class A {
public static void main(String[] args) throws IOException {
new Thread(){
@Override
public void run() {
try {
DatagramSocket datagramSocket = new DatagramSocket(9889);
while (true) {
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
datagramSocket.receive(packet);
String ip = packet.getAddress().getHostAddress(); //获取发送者的ip
byte[] data = packet.getData();
String s = new String(data, 0, packet.getLength());
System.out.println("B:发来消息" + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
sendMsg();
}
private static void sendMsg() {
DatagramSocket datagramSocket = null;
try {
datagramSocket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入发送的消息");
while (scanner.hasNextLine()) {
System.out.println("请输入发送的消息");
String msg = scanner.nextLine();
byte[] bytes = msg.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.8.41"), 9889);
datagramSocket.send(packet);
}
} catch (IOException e) {
e.printStackTrace();
}
datagramSocket.close();
}
}
public class B {
public static void main(String[] args) throws IOException {
new Thread() {
@Override
public void run() {
try {
DatagramSocket datagramSocket = new DatagramSocket(9889);
while (true) {
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
datagramSocket.receive(packet);
String ip = packet.getAddress().getHostAddress(); //获取发送者的ip
byte[] data = packet.getData();
String s = new String(data, 0, packet.getLength());
System.out.println("A:发来消息" + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
sendMsg();
}
private static void sendMsg() {
DatagramSocket datagramSocket = null;
try {
datagramSocket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入发送的消息");
while (scanner.hasNextLine()) {
System.out.println("请输入发送的消息");
String msg = scanner.nextLine();
byte[] bytes = msg.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.8.41"), 9889);
datagramSocket.send(packet);
}
} catch (IOException e) {
e.printStackTrace();
}
datagramSocket.close();
}
}
2、编写程序,通过TCP协议,完成客户端上传文件到服务器端
public class TCPClient {
public static void main(String[] args) throws IOException{
Socket socket = new Socket("192.168.8.41", 9889);
OutputStream out = socket.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
BufferedReader reader = new BufferedReader(new FileReader("aa.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.flush();
}
reader.close();
socket.close();
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9889);
System.out.println("服务器等待中....");
Socket socket = ss.accept();
InputStream in = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\aa.txt"));
String line=null;
while ((line=reader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedWriter.close();
ss.close();
}
}
3、编写程序,通过TCP协议,完成多线程版本客户端上传文件到服务器端,服务器端给出反馈
public class TCPClient {
public static void main(String[] args) throws IOException{
Socket socket = new Socket("192.168.8.41", 9889);
OutputStream out = socket.getOutputStream();
//包装通道中的输出流
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
//创建一个输入流,来关联这个文本文件
BufferedReader reader = new BufferedReader(new FileReader("b.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.flush();
}
socket.shutdownOutput();
//读取服务端的反馈
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes, 0, len));
reader.close();
socket.close();
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9889);
System.out.println("服务器等待中....");
Socket socket = ss.accept();
InputStream in = socket.getInputStream();
//把通道中的输入流包装成字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
//关联一个输出流
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\b.txt"));
String line=null;
while ((line=reader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
System.out.println("--------------");
//给客户端一个反馈
OutputStream outputStream = socket.getOutputStream();
outputStream.write("文件上传成功".getBytes());
bufferedWriter.close();
ss.close();
}
}
4、编写程序,通过TCP协议,完成多线程版本客户端上传文件到服务器端,服务器端给出反馈。
public class TCPClient {
public static void main(String[] args) throws IOException{
Socket socket = new Socket("192.168.8.41", 9889);
//获取通道中的输出流
OutputStream out = socket.getOutputStream();
//包装通道中的输出流
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
//创建一个输入流,来关联这个文本文件
BufferedReader reader = new BufferedReader(new FileReader("c.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.flush();
}
socket.shutdownOutput();
//读取服务端的反馈
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes, 0, len));
reader.close();
socket.close();
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
//服务端上传文件完成了之后,给客户端一个反馈
ServerSocket ss = new ServerSocket(9889);
System.out.println("服务器等待中....");
int i=1;
while (true){
Socket socket = ss.accept();
System.out.println((i++)+"个客户端已经连接");
new ServerThread(socket).start();
}
}
}
public class ServerThread extends Thread {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
//把通道中的输入流包装成字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
//关联一个输出流
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.currentTimeMillis()+"cc.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
System.out.println("----------------");
//保存完毕后,给客户端一个反馈
OutputStream outputStream = socket.getOutputStream();
outputStream.write("文件上传成功".getBytes());
//释放资源
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}