IP地址的组成:
具有唯一性,唯一标识网络的每一台计算机
32位,由四个8位二进制数组成
IP地址 = 网络地址+主机地址
网络地址:表示计算机或者网络设备所在的网段
主机地址:表示特定主机或网络设备
IP地址的配置和检测
查看主机ip地址:ipconfig
测试网络是否通畅:ping 目标IP地址
DNS域名解析
DNS:Domain Name System,域名系统
网络通信协议
应用层,传输层,网络层,数据链路层,物理层
Scoket简介
Scoket的底层机制复杂,java平台提供了一些简单的API,可以更简单有效的使用Socket开发无需了解底层机制
基于TCP协议的Socket编程
用来实现双向安全链接网络通信
Socket网络编程一般可以分为以下步骤
建立链接----》打开Socket关联的输入输出流----》数据流中读写信息----》关闭所以的数据流和Socket
传递字符串:
//客户端
public static void main(String[] args) {
//创建通信链路的端点客户端套字节
Socket socket =null;
InputStream is=null;
OutputStream os = null;
BufferedReader br =null;
try {
socket = new Socket("127.0.0.1", 10086);
//利用socket.getOutputStream()方法来向服务器进行输出内容
os = socket.getOutputStream();
String str = "用户名:小玉 ,密码:123456";
byte[] b = str.getBytes();
os.write(b);
System.out.println("我是客户端,数据放完毕");
//关闭数据流
socket.shutdownOutput();
//接受服务器响应
is=socket.getInputStream();
//再利用缓冲流BufferedReader来更高效读取
br = new BufferedReader(new InputStreamReader(is));
String str1 = br.readLine();
System.out.println("我是客户端,接收到的服务器端响应信息为:"+str1);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
os.close();
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//服务器端
public static void main(String[] args) {
//创建ServerSocket对象来实现服务器的客户端
ServerSocket ss = null;
Socket socket = null;
InputStream is=null;
BufferedReader br =null;
OutputStream os = null;
try {
ss = new ServerSocket(10086);
//利用accept()方法监听方法来进行服务器等待
socket= ss.accept();
is= socket.getInputStream();
//利用更高效率的BufferedReader来读取数据
br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();
System.out.println("我是服务器,客户端反馈给我的是:"+str);
//关闭输入流
socket.shutdownInput();
//服务器要给客户端一个响应
os =socket.getOutputStream();
String str1 = "用户名和密码正确";
byte[] b = str1.getBytes();
os.write(b);
System.out.println("给客户端相应完毕");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
os.close();
br.close();
is.close();
socket.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
传递对象信息:
//客户端
public static void main(String[] args) {
//创建学生类对象
Student stu = new Student("小小", 40, "女");
//创建客户端Socket
Socket socket = null;
OutputStream os= null;
ObjectOutputStream oos = null;
InputStream is = null;
BufferedReader br = null;
try {
socket = new Socket("127.0.0.1", 10010);
//给服务器发送对象
os= socket.getOutputStream();
//要序列化对象传输
oos = new ObjectOutputStream(os);
oos.writeObject(stu);
System.out.println("对象传输完毕");
//接收服务的响应
is =socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
String st= br.readLine();
System.out.println("这里是客户端:"+st);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
is.close();
oos.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//服务器端
public static void main(String[] args) {
//创建服务器ServerSocket对象
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ObjectInputStream ois = null;
OutputStream os= null;
try {
ss = new ServerSocket(10010);
//利用监听服务器进行等待
socket = ss.accept();
//读取客户端传来的对象
is = socket.getInputStream();
//因为是对象所以要进行反序列化
ois = new ObjectInputStream(is);
Object ob= ois.readObject();
Student st = (Student)ob;
System.out.println("这里是服务器:"+st.getAge()+","+st.getName());
//给客户端一个响应
os= socket.getOutputStream();
String str = "信息正确";
byte[] b = str.getBytes();
os.write(b);
System.out.println("给客户端反馈响应"+st);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
os.close();
ois.close();
is.close();
socket.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Socket编程总结:
客户端通过输出流将请求信息发送给服务器
服务器通过输入流读取客户端的请求信息
服务器端通过输出流将响应的信息发送给客户端
客户端通过输入流读取服务器端的响应信息
多线程处理多请求
实现多客户请求:蚕蛹多线程的方式,一个专门负责监听的应用住服务程序,一个专门负责处理请求的线程程序
多个客户端向服务器发送请求,服务器怎么办?
客户端跟之前一样做的事情没有发生改变:
客户端通过输出流发送请求信息
客户端通过输入流来获取服务器端响应的信息
服务器跟之前做的事情不一样:
服务器端利用循环监听客户端的请求,监听到一个请求就会获取一个Socket类的对象,将这个Socket类对象作为参数传递给服务器线程类的有参构造方法里面去
服务器线程类通过获取Socket类对象去执行原来的服务器所做的事情
通过输入流获取客户端的请求
通过输出流发送响应信息的客户端
//服务器线程类
public class ServerThread extends Thread{//要继承Thread类
//声明一个Socket类型的属性
private Socket socket;
public ServerThread(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
InputStream is= null;
ObjectInputStream ois = null;
OutputStream os = null;
try {
//通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息
is= socket.getInputStream();
ois = new ObjectInputStream(is);
Object ob= ois.readObject();
Perpon pp = (Perpon)ob;
System.out.println("我这边是服务器:客户发送给我的数据是:"+pp.getAge()+pp.getName());
//服务器接受客户端消息后需要给客户端一个响应信息
os = socket.getOutputStream();
String str = "信息正确";
byte[] b= str.getBytes();
os.write(b);
System.out.println("给客户端响应成功");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
os.close();
ois.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服务器端
public static void main(String[] args) {
//创建ServerSocket对象来实现服务器的客户端
ServerSocket ss = null;
Socket socket = null;
try {
ss = new ServerSocket(10086);
while(true){
//利用accept()方法监听方法来进行服务器等待
socket= ss.accept();
//将获取到的socket对象传递到线程类中
ServerThread st = new ServerThread(socket);
st.start();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端
public static void main(String[] args) {
//创建通信链路的端点客户端套字节
Socket socket =null;
OutputStream os = null;
ObjectOutputStream oos = null;
InputStream is=null;
BufferedReader br =null;
try {
socket = new Socket("127.0.0.1", 10086);
//利用socket.getOutputStream()方法来向服务器进行输出内容
os = socket.getOutputStream();
Perpon stu = new Perpon("张三", 15, "男");
oos = new ObjectOutputStream(os);
oos.writeObject(stu);
System.out.println("我是客户端,数据放完毕");
//关闭数据流
socket.shutdownOutput();
//接受服务器响应
is=socket.getInputStream();
//再利用缓冲流BufferedReader来更高效读取
br = new BufferedReader(new InputStreamReader(is));
String str1 = br.readLine();
System.out.println("我是客户端1,接收到的服务器端响应信息为:"+str1);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
is.close();
oos.close();
os.close();
//socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
基于UDP协议的Socket网络变成步骤
利用DatagramPacket对象封装数据包------》利用DatagramSocket发送数据包---》利用DatagramSocket接受数据包---》利用DatagramPacket处理数据包
//服务器
public static void main(String[] args) {
//创建服务器
byte[] infos = new byte[1024];
DatagramPacket dp = new DatagramPacket(infos, infos.length);
DatagramSocket socket = null;
try {
socket = new DatagramSocket(5000);
//接受客户端的数据包,并将信息封装在dp中
socket.receive(dp);
//构建一个字符串
String info = new String(dp.getData(), 0, dp.getData().length);
System.out.println("客户端:"+info);
//给客户端一个响应
String reply = "您好,我在请说!";
//给客户端的地址
SocketAddress sa = dp.getSocketAddress();
//打开一个包裹
DatagramPacket dp1 = new DatagramPacket(reply.getBytes(), 0, reply.getBytes().length);
//将包裹寄走
socket.send(dp1);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
socket.close();
}
}
//客户端
public static void main(String[] args) {
//创建客户端
String info = "您好!我想问你一个问题!";
byte[] infos = info.getBytes();
InetAddress ia= null;
DatagramSocket socket = null;
try {
ia = InetAddress.getByName("localhost");
//构建客户端要发送的数据包对象
DatagramPacket dp = new DatagramPacket(infos, infos.length, ia, 5000);
//客户端需要一个DatagramSocket对象
socket = new DatagramSocket();
//通过DatagramSocket对象发送数据包到服务器
socket.send(dp);
//接受服务器响应
byte[] replys = new byte[1024];
DatagramPacket dp1 = new DatagramPacket(replys, replys.length);
socket.receive(dp1);
String reply = new String(dp1.getData(), 0, dp1.getData().length);
System.out.println("服务器回应:"+reply);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//释放资源
socket.close();
}
}