网络编程
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
可以计算机之间相互通信,并进行数据传输
一、InetAddress类的使用:
如果一个类没有构造方法:
A:成员全部是静态的(Math,Arrays,Collections)
B:单例设计模式(Runtime)
C:类中有静态方法返回该类的对象(InetAddress)
class Demo{
privateDemo(){}
publicstatic Demo getXxx() {
return newDemo();
}
}
InetAddress类通过getLocalHost etByName 获取对象
要掌握的功能
获取本地主机:getLocalHost
InetAddressaddress =InetAddress.getLocalHost();
获取任意指定主机:getByName
InetAddressaddress = InetAddress.getByName("fada-PC");
主机Ip地址:getHostAddress
String ip= address.getHostAddress();
主机名:getHostName
Stringname = address.getHostName();
二、网络通信三要素
IP地址:InetAddress :网络中设备的标识,不易记忆,可用主机名
端口号 :用于标识进程的逻辑地址,不同进程的标识
物理端口 网卡口
逻辑端口 我们指的就是逻辑端口
A:每个网络程序都会至少有一个逻辑端口
B:用于标识进程的逻辑地址,不同进程的标识
C:有效端口:0~65535,其中0~1024系统使用或保留端口。自已定义一般在1万以上
通过360可以查看端口号
传输协议:通讯的规则 ---常见协议:TCP,UDP
UDP
将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快
TCP
建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低
Socket
用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
Socket就是为网络编程提供的一种机制;通信的两端都有Socket;网络通信其实就是Socket间的通信;数据在两个Socket间通过IO传输。
三、UDP协议传输数据代码实现步骤
UDP协议接收数据:
A:创建接收端Socket对象
B:创建一个数据包(接收容器)
C:调用Socket对象的接收方法接收数据
D:解析数据包,并显示在控制台
E:释放资源
UDP协议发送数据:
A:创建发送端Socket对象
B:创建数据,并把数据打包
C:调用Socket对象的发送方法发送数据包
D:释放资源
代码实现:
packagecn.itcast_05;
importjava.io.IOException;
importjava.net.DatagramPacket;
importjava.net.DatagramSocket;
publicclass ReceiveThread implements Runnable {
privateDatagramSocket ds;
publicReceiveThread(DatagramSocket ds) {
this.ds =ds;
}
@Override
publicvoid run() {
try {
while(true) {
创建一个包裹
byte[] bys= new byte[1024];
DatagramPacketdp = new DatagramPacket(bys, bys.length);
接收数据
ds.receive(dp);
解析数据
String ip= dp.getAddress().getHostAddress();
String s =new String(dp.getData(), 0, dp.getLength());
System.out.println("from" + ip + " data is : " + s);
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
packagecn.itcast_05;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
import java.net.DatagramPacket;
importjava.net.DatagramSocket;
importjava.net.InetAddress;
publicclass SendThread implements Runnable {
privateDatagramSocket ds;
publicSendThread(DatagramSocket ds) {
this.ds =ds;
}
@Override
publicvoid run() {
try {
//封装键盘录入数据
BufferedReaderbr = new BufferedReader(new InputStreamReader(
System.in));
Stringline = null;
while((line = br.readLine()) != null) {
if("886".equals(line)) {
break;
}
//创建数据并打包
byte[] bys= line.getBytes();
DatagramPacketdp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.12.92"),12345);
DatagramPacketdp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.12.255"),12306);
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
//多线程启动聊天程序
packagecn.itcast_05;
importjava.io.IOException;
importjava.net.DatagramSocket;
publicclass ChatRoom {
publicstatic void main(String[] args) throws IOException {
DatagramSocketdsSend = new DatagramSocket();
DatagramSocketdsReceive = new DatagramSocket(12306);
SendThreadst = new SendThread(dsSend);
ReceiveThreadrt = new ReceiveThread(dsReceive);
Thread t1= new Thread(st);
Thread t2= new Thread(rt);
t1.start();
t2.start();
}
}
四、TCP协议传输数据步骤
TCP协议接收数据:
A:创建接收端的Socket对象
B:监听客户端连接。返回一个对应的Socket对象
C:获取输入流,读取数据显示在控制台
D:释放资源
TCP协议发送数据:
A:创建发送端的Socket对象
这一步如果成功,就说明连接已经建立成功了。
B:获取输出流,写数据
C:释放资源
连接被拒绝。TCP协议一定要先看服务器。
java.net.ConnectException:Connection refused: connect
代码实现:
packagecn.itcast_15;
import java.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.FileReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.net.Socket;
publicclass UploadClient {
publicstatic void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s =new Socket("192.168.12.92", 11111);
//封装文本文件
BufferedReaderbr = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
BufferedReaderbr = new BufferedReader(new FileReader(
"ReceiveDemo.java"));
//封装通道内流
BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
Stringline = null;
while((line = br.readLine()) != null) { //阻塞
bw.write(line);
bw.newLine();
bw.flush();
}
//Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
s.shutdownOutput();
//接收反馈
BufferedReaderbrClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
Stringclient = brClient.readLine(); //阻塞
System.out.println(client);
//释放资源
br.close();
s.close();
}
}
packagecn.itcast_15;
importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.net.Socket;
publicclass UserThread implements Runnable {
private Sockets;
publicUserThread(Socket s) {
this.s =s;
}
@Override
publicvoid run() {
try {
//封装通道内的流
BufferedReaderbr = new BufferedReader(new InputStreamReader(
s.getInputStream()));
//封装文本文件
BufferedWriterbw = new BufferedWriter(new
FileWriter("Copy.java"));
//为了防止名称冲突
StringnewName = System.currentTimeMillis() + ".java";
BufferedWriterbw = new BufferedWriter(new FileWriter(newName));
Stringline = null;
while((line = br.readLine()) != null) { //阻塞
bw.write(line);
bw.newLine();
bw.flush();
}
//给出反馈
BufferedWriterbwServer = new BufferedWriter(
newOutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush();
//释放资源
bw.close();
s.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
packagecn.itcast_15;
importjava.io.IOException;
importjava.net.ServerSocket;
importjava.net.Socket;
publicclass UploadServer {
publicstatic void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocketss = new ServerSocket(11111);
while(true) {
Socket s =ss.accept();
newThread(new UserThread(s)).start();
}
}
}