1. 网络编程的三要素:IP地址、端口、协议
2. 端口号:
正在运行的程序的标识。
有效端口:0~65535,其中0~1024系统使用或保留端口。
3. 协议:
通信的规则
(1)UDP: (2)TCP:
(1.1)把数据打包 (2.1)
建立连接通道
(1.2)数据有限制 (2.2)数据无限制
(1.3)不建立连接 (2.3)
速度慢
(1.4)速度快 (2.4)可靠
(1.5)不可靠
4. .获取本机的Ip地址
/* public static InetAddress getByName(String host)throws UnknownHostException
* 在给定主机名的情况下确定主机的 IP 地址。 主机名可以是机器名(如 "java.sun.com"),
* 也可以是其 IP 地址的文本表示形式。如果提供字面值 IP 地址,则仅检查地址格式的有效性。
*/
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
// InetAddress address=InetAddress.getByName("xiaofeng");
InetAddress address = InetAddress.getByName("192.168.147.112");
// String getHostName() 获取此 IP 地址的主机名。
String name = address.getHostName();
//返回:此 IP 地址的主机名;如果安全检查不允许操作,则返回 IP 地址的文本表示形式。
// String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
String ip = address.getHostAddress();
System.out.println(name + "---" + ip);
}
}
5. 多线程实现聊天案例---UDP协议
public class UdpDemo {
public static void main(String[] args) throws IOException{
//创建客户端Socket对象
//public class DatagramSocket extends Object 此类表示用来发送和接收数据报包的套接字。
DatagramSocket ds=new DatagramSocket();
//创建服务器端Socket对象
//public DatagramSocket(int port) 指定的端口
DatagramSocket dss=new DatagramSocket(20000);
//用于发送数据的实现类
SendMessage sm=new SendMessage(ds);
//用于接受数据的实现类
ReceiveMessage rm=new ReceiveMessage(dss);
//创建多线程对象
Thread t1=new Thread(sm);
Thread t2=new Thread(rm);
//开始线程
t1.start();
t2.start();
}
}
public class SendMessage implements Runnable {
private DatagramSocket ds;
// 通过构造得到DatagramSocket对象
public SendMessage(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
// 从键盘录入数据,用字符流包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 读取数据
String line = null;
while ((line = br.readLine()) != null) {
//给出终止条件 如果输入over,则终止循环,释放资源
if(line.equals("over")){
break;
}
/*
* 创建数据包 DatagramPacket(byte[] buf, int length, InetAddress
* address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
*/
DatagramPacket dp = new DatagramPacket(line.getBytes(), line.getBytes().length,
InetAddress.getByName("192.168.1.108"), 20000);
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
public class ReceiveMessage implements Runnable {
private DatagramSocket ds;
// 通过构造得到DatagramSocket对象
public ReceiveMessage(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
while (true) {
// 创建一个接受容器去接受数据包
// DatagramPacket(byte[] buf, int length)构造 DatagramPacket,用来接收长度为
// length 的数据包。
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 调用socket对象的接受方法接受数据
try {
ds.receive(dp);// 阻塞式方法
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 解析数据包,并显示在控制台
// public byte[] getData() 获取数据缓冲区
// public int getLength() 获取数据的实际长度
System.out.println(new String(dp.getData(), 0, dp.getLength()));
}
5. 多个客户端上传文件 tcp
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(12345);
while(true){
//监听客户端
Socket s=ss.accept();
new Thread(new ServerDemo(s)).start();
}
public class ServerDemo implements Runnable {
private Socket s;
public ServerDemo(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
// 封装通道内流
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
// 封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.jpg"));
// 读取数据,并写入目录
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}
// 服务器端给出反馈
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write("文件接收完毕!");
bw.newLine();
bw.flush();
// 关闭资源
// ss.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
// 创建发送端Socket对象
Socket s = new Socket("192.168.1.108", 12345);
// 封装图片目录
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("D:\\pictures\\fresh_fruit_dessert_photo_JT116.jpg"));
// 封装通道内流
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}
//终止发送
s.shutdownOutput();
// 接受服务器的反馈
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String sentence = br.readLine();
System.out.println(sentence);
// 关闭资源
s.close();
bis.close();