1、网络编程(理解)
用Java语言实现计算机间数据的信息传递和资源共享
2、网络编程模型
3、网络编程的三要素
A:IP地址
a:点分十进制
b:IP地址的组成
c:IP地址的分类
d:dos命令
e:InetAddress
回顾:如果有一个类没有构造方法的三种情况
e1:成员全部是静态的(Math, Array, Collection)
e2:单例设计模式(Runtime)
public class Student {
// 构造私有
private Student() {
}
// 自己造一个
// 静态方法只能访问静态成员变量,加静态
// 为了不让外界直接访问修改这个值,加private
private static Student s = new Student();
// 提供公共的访问方式
// 为了保证外界能够直接使用该方法,加静态
public static Student getStudent() {
return s;
}
}
e3:类中有静态方法返回该类的对象(InetAddress)
class Demo{
private Demo(){}
public static Demo getXXX(){
return new Demo();
}
}
InetAddress成员变量方法:
public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到的IP地址对象
InetAddress address = InetAddress.getByName("baron");
InetAddress address = InetAddress.getByName)("192.168.12.63");
String name = address.getHostName(); //获取主机名
String ip = address.getHostAddress(); //获取主机ip地址
B:端口
是应用程序的标识。范围:0-65535。其中0-1024不建议使用。
C:协议
UDP:数据打包,有限制64k,不连接,效率高,不可靠
TCP:建立数据通道,无限制,效率低,可靠(三次握手协议)
4、Socket机制
Socket = IP + Port
A:通信两端都应该有Socket对象
B:所有的通信都是通过Socket间的IO进行操作的
5、UDP协议发送和接收数据(掌握)
发送:
创建UDP发送端的Socket对象
创建数据并把数据打包
调用Socket对象的发送方法,发送数据包
释放资源
代码案例:
public static void main(String[] args) throws IOException {
// 创建发送端Socket对象
// DatagramSocket()
DatagramSocket ds = new DatagramSocket();
// 创建数据,并把数据打包
// DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// 创建数据
byte[] bys = "hello,udp,我来了".getBytes();
// 长度
int length = bys.length;
// IP地址对象
InetAddress address = InetAddress.getByName("192.168.12.92");
// 端口
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys, length, address, port);
// 调用Socket对象的发送方法发送数据包
// public void send(DatagramPacket p)
ds.send(dp);
// 释放资源
ds.close();
}
接收:
创建UDP接收端的Socket对象
创建数据包用于接收数据
接收数据
解析数据包
释放资源
代码案例:
public static void main(String[] args) throws IOException {
// 创建接收端Socket对象
// DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(10086);
// 创建一个数据包(接收容器)
// DatagramPacket(byte[] buf, int length)
byte[] bys = new byte[1024];
int length = bys.length;
DatagramPacket dp = new DatagramPacket(bys, length);
// 调用Socket对象的接收方法接收数据
// public void receive(DatagramPacket p)
ds.receive(dp); // 阻塞式
// 解析数据包,并显示在控制台
// 获取对方的ip
// public InetAddress getAddress()
InetAddress address = dp.getAddress();
String ip = address.getHostAddress();
// public byte[] getData():获取数据缓冲区
// public int getLength():获取数据的实际长度
byte[] bys2 = dp.getData();
int len = dp.getLength();
String s = new String(bys2, 0, len);
System.out.println(ip + "传递的数据是:" + s);
// 释放资源
ds.close();
}
6、多线程实现的第三种方案
实现Callable接口,与Runnable类似
代码案例--10
7、TCP协议发送和接收数据(掌握)
发送:
创建TCP客户端的Socket对象
如果成功,说明已经已经成功建立连接
获取输出流,写数据
释放资源
代码案例:
/*
* 按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?
* 读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。
* 所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。
*
* 如何解决呢?
* A:在多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。
* 这样做可以解决问题,但是不好。
* B:Socket对象提供了一种解决方案
* public void shutdownOutput()
* s.shutdownOutput();
*/
public static void main(String[] args) throws IOException{
//创建发送端Socket对象
//Socket(InetAddress address, int port)
//Socket(String host, int port)
//Socket s = new Socket(InetAddress.getByName(), 8888);
Socket s = new Socket("192.168.12.92", 8888);
//获取输出流,写数据
public OutputStream getOutputStream()
OutputStream os = s.getOutputStream();
os.write("hello tcp".getBytes());
//释放资源
s.close();
}
接收:
创建TCP服务器端的Socket对象
监听客户端连接,返回对应Socket对象
获取输入流,读取数据
释放资源
代码案例:
public static void main(String[] args) throws IOException{
//创建接受端的Socket对象
//ServerSocket(int port)
ServerSocket ss = new ServerSocket(8888);
//监听客户端连接
//public Socket accept();
Socket s = ss.accept();
//获取输入流,读取数据
InputStream is = s.getInputStream(); //侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞
byte[] bys = new byte[1024];
int len = is.read(bys); //阻塞式方法
String str = new String(bys,0,len);
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip +"---"+ str);
//释放资源
s.close();
//ss.close(); 这个不应该关
}
8、案例
A:UDP
a:最基本的UDP协议发送和接收数据
b:把发送数据改进为键盘录入
c:一个简易聊天小程序并用多线程改进
B:TCP
a:最基本的TCP协议发送和接收数据
b:服务器给出反馈
c:客户端键盘录入服务器控制台输出
d:客户端键盘录入服务器写到文本文件
e:客户端读取文本文件服务器控制台输出
f:客户端读取文本文件服务器写到文本文件
g:上传图片
h:多线程改进上传文件