第二章 网络编程
文章目录
1.常见的类
URL:构造方法 URL(String url)
获取网络输入流:InputStream openStream()
获取网络连接的:URLConnection openConnection()
关闭连接:close()
URLConnection(HTTPURLConnection):
获取网络输入流:InputStream getInputStream()
获取网络输出流:OutputStream getOutputStream()
关闭连接:close()
Socket:用于客户端类,构造方法 Socket(String addr, int port)
获取网络输入流:InputStream getInputStream()
获取网络输出流:OutputStream getOutputStream()
关闭连接:close()
ServerSocket:用于服务端监听端口的类,ServerSocket(int port)
接收客户端连接的方法:Socket accept()
获取网络输入流:InputStream getInputStream()
获取网络输出流:OutputStream getOutputStream()
关闭连接:close()
DatagramSocket:
构造方法: DatagramSocket()、DatagramSocket(int port)
发送数据包:send(DatagramPacket p)
接收数据包:receive(DatagramPacket p)
DatagramPacket:
构造方法:DatagramPacket(byte[] bytes, int length)
DatagramPacket(byte[] bytes, int length,InetAddress assr, int port)
InetAddress:获取对象方法:InetAddress. getByName(String host)
设置数据包参数方法:
setData(byte[] bytes) 设置数据
setInetAddress(InetAddress addr) 设置连接的目标主机
setPort(int port) 设置端口号
获取数据包参数方法:
InetAddress getAddress() 获取发送方地址
Int getPort() 获取发送方的端口号
byte[] getData() 获取发送的数据
备注:
通过InetAddress对象获取主机IP地址的方法:
String getHostAddress()方法
2. Socket网络编程步骤(TCP)
客户端:
1. 建立连接
2. 获取流
3. 流的读写
4. 关闭连接
服务端:
1. 监听端口
2. 获取客户端连接
3. 获取流
4. 流的读写
5. 关闭连接
3. 常用的流
字节流:
InputStream、OutputStream:网络中获取到的流
FileInputStream、FileOutputSteam:操作本地文件的流
字符流:
BufferedReader(String readLine())、
BufferedWriter(write(String str)、newLine())
高级缓冲字符流使用注意事项:
1. 避免中文乱码,指定编码方式
2. 不会自动写入换行符
4. UDP网络编程步骤
1)构造DatagramSocket对象
2)构造DatagramPacket对象
3)发送/接收数据
4)关闭
File aim1=new File(num1);
File aim2=new File(num2);
if(aim1.exists() && aim2.exists())
{
if(aim1.isFile() && !aim2.isFile() ) {
System.out.println("输入路径有效");
try {
FileInputStream input = new FileInputStream(aim1);
String name=aim1.getName();
FileOutputStream output = new FileOutputStream(aim2+"/"+name);
int num=0;
while(num!=-1) {
num=input.read();
output.write(num);
}
input.close();
output.close();
}catch(IOException e){
e.printStackTrace();
}
}
}else {
System.out.println("输入路径无效,,请重新输入");
}
//字符流
FileReader input = new FileReader(f1);
FileWriter outpute =new FileWriter(f2,false);
char[] list=new char[1024];
int number=input.read(list);
while(number!=-1)
{
outpute.write(list,0,number);
outpute.flush();
number=input.read(list);
}
input.close();//关
outpute.close();
基础知识
-
计算机网络:通过一定的物理设备将处于不同位置的计算 机连接起来组成的网络 – 网络最主要的作用在于共享设备和传输数据。
-
为了准确地定位网络上的目标主机,网络中的每个设备都 会有一个唯一的数字标识,即网络设备的IP地址 –
- 通过IP地址,可精确地匹配目标主机,是网络中资源共享、数据传输的依据 –
- 例如:欲查找当前局域网内打印机,可通过其IP地址10.7.10.200精确匹配 •
-
由于IP地址不易记忆,引入网络域名来确认IP地址 – 例如:域名www.baidu.com相对于119.75.218.77来说,更容易记忆
1. 网络编程简介
1.1. 定义
- 网络编程是指通过编程方式实现两个(或多个)设备之间 的数据传输
- – 网络编程是基于“请求-响应”模式的:网络中某一端发出请求,另一端接 收到请求后,响应请求方的请求 –
- “请求方”称之为客户端,“响应方”称之为服务器端 –
- 网络编程在客户端和服务器端之间传输数据可以采用TCP方式,也可以采用 UDP方式
1.2. 两种编程模式
- 网络编程开发模式 –
- 客户端/服务器端模式(C/S模式):对于不同的服务器端程序建立不同的 客户端程序 –
- 浏览器/服务器端模式(B/S模式):对于不同的服务器端程序使用统一的 “客户端”(即浏览器)即可
1.3. Java网络编程核心类
1.4. URL及应用
- 使用Socket进行网络编程,从网络传输层角度进行分析, 适用于绝大多数网络连接方式;但是需要开发人员熟练掌 握网络传输、网络协议等基础知识,开发难度较大 •
- 在Java语言中,提供了一组URL处理类,封装了Socket编 程技术的实现细节,用来方便开发人员进行网络连接、网 络数据传输等常用的网络任务 –
- 直接使用URL类,可以方便地处理各种常见协议的网络连接 –
- 使用URL类进行网络连接,相当于直接进行远程输入/输出流操作,只需开 发人员熟练掌握常用IO操作即可,大大降低开发难度
1.5. URL网络编程核心操作类
1.6.URL类
URL myURL = new URL("http://java.sun.com");
String protocal = myURL.getProtocol();
String host = myURL.getHost();
String file = myURL.getFile();
int port = myURL.getPort();
String ref = myURL.getRef();
System.out.println(protocal + ", " + host + ", " + file + ", " + port + ", " + ref);
课上代码--下载小黄人
try {
1. 创建URL对象
URL myUrl=new URL("https://editor.csdn.net/md/?articleId=104767696");
2. 获取网络输入流
InputStream input=myUrl.openStream();
3. 获取本地输入流
OutputStream out=new FileOutputStream("C:\\Users\\yxmia\\Desktop/123.html");
4. 循环读写
int num=input.read();
while(num!=-1) {
out.write(num);
num=input.read();
}
5. 关闭流
input.close();
out.close();
System.out.println("图片下载成功");
}catch(IOException e) {
e.printStackTrace();
}
1.7 URL Connection类
url = new URL("http://");
// 打开连接
URLConnection conn = url.openConnection();
// 得到输入流
InputStream is = conn.getInputStream();
// 关于IO流的用法和写法一定要熟悉
OutputStream os = new FileOutputStream("d:\\baidu.png");
byte[] buffer = new byte[2048];
int length = 0;
while (-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer, 0, length);
}
is.close(); os.close();
2. Scoket
2.1. • Socket通信
2.1.1. 简介
- 客户端和服务器端建立连接后,连接两端将会建立一个虚
拟“线缆”,在网络编程中称之为Socket(套接字);其
后在网络两端传输数据都是通过Socket进行的
– Socket借助IP地址和端口号,对应某一台主机中的某一个应用程序
– Socket的主要作用是维护网络连接、在网络双方传输数据
- Socket类:客户端套接字类。实现客户端向服务器发送数
据、接收服务器数据等功能;实现服务器端向客户端发送
数据、接收客户端数据等功能
– 其它方法查看:
http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html
客户端Socket请求服务器内容
Socket client = new Socket("127.0.0.1", 8888);
//127.0.0.1是默认本地地址,也能写localhost
// 获得网络输入/输出流
InputStream is = client.getInputStream(); // 获得网络输入流
OutputStream os = client.getOutputStream(); // 获得网络输出流
// 发送数据到server
String request = "this is a client request!";
os.write(request.getBytes());
os.flush();// 刷新请求
// 接收响应
byte[] b = new byte[1024];
StringBuffer strb = new StringBuffer();
while (is.read(b) != -1) {
strb.append(new String(b));
}
System.out.println(strb.toString());
// 关闭连接
is.close();
os.close();
client.close();
]
2.2. • Socket通信的过程
2.2.1. 客户端
public class KeHuDuan {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建Scoket对象
try {
Socket client=new Socket("127.0.0.1",8888);
//获取网络输出流
OutputStream out=client.getOutputStream();
//发送数据
System.out.println("开始发送数据");
String message=new String("hello world");
out.write(message.getBytes());
//getbytes(),字符串转换成字节数组
//关闭链接
out.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2.2. 服务器
2.3. • Socket基于TCP协议的网络编程
public class FuWuQi {
public static void main(String[] args) {
// TODO Auto-generated method stub
//服务器端
try {
//监听端口
ServerSocket server=new ServerSocket(8888);
//获取连接对象
Socket client=server.accept();
//获得网络输入流
InputStream in=client.getInputStream();
//读取流
byte[] list=new byte[1024];
in.read(list);
String message=new String(list);
System.out.println("收到数据");
//关闭
in.close();
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
完整接受代码
//服务器端接受与发送数据
try {
//监听端口
ServerSocket server=new ServerSocket(8888);
//获取客户端链接
System.out.println("等待连接");
Socket client=server.accept();
//获取输入流,用于接收数据
InputStream in=client.getInputStream();
//读取数据
byte[] list=new byte[1024];
in.read(list);
System.out.println("收到的数据为"+new String(list));
//获得输出流,用于发送数据
OutputStream out=client.getOutputStream();
//写数据
String message=new String("数据已收到,请知晓");
out.write(message.getBytes());
//关闭连接
in.close();
out.close();
client.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
//客户端
try {
//创建客户端Scoket对象
Socket client=new Socket("localhost",8888);
//获取网络输出流,用于发送数据
OutputStream out=client.getOutputStream();
//发送数据
System.out.println("发送数据");
String message=new String("这就是发送的数据");
out.write(message.getBytes());
//获取网络输入流,接收数据
InputStream in=client.getInputStream();
//读数据
byte[] list=new byte[1024];
in.read(list);
message=new String(list);
System.out.println("客户收到的数据为"+message);
//关闭流
in.close();
out.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
多线程实现服务器接受信息与发送信息
服务器
//服务器端接受与发送数据
try {
//监听端口
ServerSocket server=new ServerSocket(8888);
while(true) {
//获取客户端链接
System.out.println("等待连接");
Socket client=server.accept();
//创建子线程与客户端交互,子线程
FuWuQiThread jiaohu=new FuWuQiThread(client);
jiaohu.start();
}
//server.close(); //一般不关闭
} catch (IOException e) {
e.printStackTrace();
}
}
public class FuWuQiThread extends Thread{
private Socket client;
public static int num=0;
public FuWuQiThread(Socket num) {
this.client=num;
}
@Override
public void run() {
++num;
try {
//获取输入流,用于接收数据
InputStream in = client.getInputStream();
//读取数据
byte[] list=new byte[1024];
in.read(list);
System.out.println("第"+num+"次收到的数据为"+new String(list));
//获得输出流,用于发送数据
OutputStream out=client.getOutputStream();
//写数据
String message=new String("数据已收到,请知晓");
out.write(message.getBytes());
//关闭连接
in.close();
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
public class KeHuDuan {
public static void main(String[] args) {
//客户端
try {
//创建客户端Scoket对象
Socket client=new Socket("localhost",8888);
//获取网络输出流,用于发送数据
OutputStream out=client.getOutputStream();
//发送数据
System.out.println("发送数据");
String message=new String("这就是发送的数据");
out.write(message.getBytes());
//获取网络输入流,接收数据
InputStream in=client.getInputStream();
//读数据
byte[] list=new byte[1024];
in.read(list);
message=new String(list);
System.out.println("客户收到的数据为:"+message);
//关闭流
in.close();
out.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
多线程简介
//高级流加编码方式
try {
// 监听端口
ServerSocket server = new ServerSocket(8888);
// 获取连接对象
Socket client = server.accept();
// 获得网络输入流
InputStream in = client.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(in, "utf-8"));
// 读取流
String string1=reader.readLine();//返回值字符串
String string2=reader.readLine();//返回值字符串
System.out.print(string1+"--"+string2);
in.close();
reader.close();
client.close();
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//tcp 高级流加编码方式
try {
//Socket链接
Socket client=new Socket("127.0.0.1", 8888);
//输出流
OutputStream out=client.getOutputStream();
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out,"utf-8"));
//GBK GB2312都支持中文,但是常用第二个,常用utf-8
//发数据
writer.write("下雨收衣服了");
writer.write("弄好了么");
writer.newLine();//实现换行
out.close();
writer.close();
client.close();
tcp高级流
//tcp 高级流加编码方式,高级流-1
try {
//Socket链接
Socket client=new Socket("127.0.0.1", 8888);
//输出流
BufferedWriter writer=new BufferedWriter(
new OutputStreamWriter(client.getOutputStream(),"utf-8"));
//GBK GB2312都支持中文,但是常用第二个,常用utf-8
//发数据,不能发换行
writer.write("下雨收衣服了");
writer.newLine();//实现换行
writer.write("弄好了么");
writer.newLine();//实现换行
writer.close();
client.close();
//低级字节流关闭高级流的时候关闭关闭就是关闭低级
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//高级流加编码方式 tcp
try {
// 监听端口
ServerSocket server = new ServerSocket(8888);
// 获取连接对象
Socket client = server.accept();
// 获得网络输入流
BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8"));
// 读取流
String string1=reader.readLine();//返回值字符串
String string2=reader.readLine();//返回值字符串
System.out.print(string1+"--"+string2);
reader.close();
client.close();
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2.4. • Socket基于UDP协议的网络编程
package class3;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDPsend {
public static void main(String[] args) {
//创建DatagramSocket
try {
//DatagramSocket client=new DatagramSocket();
DatagramSocket client=new DatagramSocket(6666);//与上一行效果相同,但是限制了发送的端口号
//构造DatagramPacket数据包
byte[] bytes="这是我发的信息".getBytes();
InetAddress addr=InetAddress.getByName("127.0.0.1");
//
DatagramPacket dp=new DatagramPacket(bytes, bytes.length,addr,8888);
//数据,长度,地址,端口号
//发数据包
client.send(dp);
//关闭
client.close();
} catch (SocketException e) {
e.printStackTrace();
}catch (UnknownHostException e2) {
e2.printStackTrace();
}catch(IOException e1) {
PrinterException e11;
}
}
}
package class3;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPreserve {
public static void main(String[] args) {
try {
//监听端口DatagramSocket
DatagramSocket server=new DatagramSocket(8888);
//空的数据包,接受数据
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(
bytes,bytes.length);
//接收数据
server.receive(dp);
//显示数据
InetAddress str1=dp.getAddress();//地址 217.0.0.1
String str2=new String(dp.getData());
int str3=dp.getPort();//发送人的端口号
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
//关闭
server.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}