网络通信协议:
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
HTTP与TCP有什么关系:
HTTP是TCP的应用层协议
UDP能传很大的文件吗?
能,有可能会阻塞
InetAddress
InetAddress用于封装一个Ip地址,并提供了一些与IP地址相关的方法
getByName(String host)在给定主机名的情况下确定主机的IP地址
getHostName()获取此IP地址的主机名
getHostAddress()返回IP地址字符串
public class Example01 {
public static void main(String[] args) throws Exception {
InetAddress local = InetAddress.getLocalHost();
InetAddress remote = InetAddress.getByName("www.baidu.com");
System.out.println("本机的IP地址:" + local.getHostAddress());
System.out.println("IP地址:" + remote.getHostAddress());
System.out.println("主机名为:" + remote.getHostName());
}
}
UDP
UDP是User Datagram Protocol的简称,称为用户数据报协议
- 发送端
- 打包 DatagramPacket
- 发送 DatagramSocket 用send发送
- 接收端
- 接受 DatagramSocket receive
- 拆包 DatagramPacket 用getData获取数据,getLength获取长度
- 特点
- 面向
UDP通讯
数据发送
public static void main(String[] args) {
while (true){
BufferedInputStream bis = new BufferedInputStream(System.in);
//封装数据
byte[] bytes = "曾锦铭".getBytes();
try {
//设置 要发送到的 ip和端口号
DatagramPacket dgp = new DatagramPacket(bytes,
bytes.length, InetAddress.getByName("localhost"), 6666);
DatagramSocket socket = new DatagramSocket();
socket.send(dgp);
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
数据接收
public class Receive {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(6666);
byte[] bytes = new byte[1024 * 8];
DatagramPacket packet = new DatagramPacket(bytes, 0,bytes.length);
//把数据装到packet里面
socket.receive(packet);
byte[] data = packet.getData();
int length = packet.getLength();
InetAddress address = packet.getAddress();
System.out.println(address.getHostName()+": "+address.getHostAddress());
System.out.println(new String(data,0,length));
socket.close();
}
}
TCP
TCP程序交互的流程
-
客户端
- 创建客户端的Socket对象
- 获取Socket的输出流对象
- 写数据给服务器
- 获取Socket的输入流对象
- 使用输入流,读反馈信息
- 关闭流资源
-
服务器端
- 创建服务器端ServerSocket对象,指定服务器端端口号
- 开启服务器,等待着客户端Socket对象的连接,如有客户端连接,返回客户端的Socket对象
- 通过客户端的Socket对象,获取客户端的输入流,为了实现获取客户端发来的数据
- 通过客户端的输入流,获取流中的数据
- 通过客户端的Socket对象,获取客户端的输出流,为了实现给客户端反馈信息
- 通过客户端的输出流,写数据到流中
- 关闭流资源
服务器代码
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(6666);
//开启线程接收客户端发送过来的消息
new Thread(new Runnable() {
@Override
public void run() {
try {
//监听客户端请求
Socket accept = serverSocket.accept();
//获取输入流
InputStream inputStream = accept.getInputStream();
//获取输出流
OutputStream outputStream = accept.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len=0;
//获取客户端的IP和主机名
InetAddress inetAddress = serverSocket.getInetAddress();
while ((len=inputStream.read(bytes))!=-1){
// System.out.println("客户端"+inetAddress.getHostName()+" : "+inetAddress.getHostAddress());
// System.out.println(new String(bytes,0,len));
//把客户端发送过来的消息
String s = new String(bytes, 0, len)
.replace("吗","")
.replace("?","!")
.replace("你","我");
//返回消息给客户端
outputStream.write(s.getBytes());
}
outputStream.close();
serverSocket.close();
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
客户端代码
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 6666);
//获取输出流
OutputStream outputStream = socket.getOutputStream();
//获取输出流
InputStream inputStream = socket.getInputStream();
//开启线程接受来自服务器返回的消息
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
byte[] by = new byte[1024];
int len = inputStream.read(by);
System.out.println("服务器返回数据 : " + new String(by, 0, len));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
boolean flag = true;
//循环输入数据发送给服务器
while (flag) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
if (s.equals("end")) {
break;
}
//往输出流里写
outputStream.write(s.getBytes());
}
inputStream.close();
outputStream.close();
socket.close();
}