从天津转站北京,爬到中关村到直立行走
Java
复习篇六
1.TCP/IP
网络参考模型(层次的细致划分)
OSI参考模型
TCP/IP参考模型
OSI参考模型 TCP/IP参考模型
--------------- -----------------------
应用层
表示层 应用层
会话层
---------------- -------------------
传输层 传输层
---------------- -------------------
网络层 网络层(网际层)
---------------- ------------------
数据链路层
物理层 链路层
--------------- ------------------
网络通讯要素:IP地址(IP对象的类,起名字容易记忆)
端口号
传输
协议
以
QQ————————————————————————>QQ为例:
找到对方IP,byte最大值为255
数据发送到对方指定的对应程序上,为了标识这些应用程序,所以把这些网络应用程序都用数字进行标识。
通信规则称为协议。
TCP/IP可以用在局/广域网。
本地环回地址 127.0.0.1
IPv6包括字母,数字,
UDP
将数据源和目的封装成数据包中,不需要建立连接。
每个数据报的大小
限制在64k内。
因无法连接,是不可靠协议。
不需要建立连接,速度快。
面向无连接,速度快,容易丢包,只管发送,发送到哪里,地址,端口(为了方便称呼这个数字,叫做端口,指逻辑端口)要明确出来。
聊天,
网络视频会议,邮局寄送包裹就是udp。
TCP
建立连接,形成传输数据通道
在连接中进行大数据量传输
通过3次握手完成连接,是可靠协议
必须建立连接,效率会稍低,消耗资源
下载就是TCP
Socket 就是为网路服务提供的一种机制。
通信的两端都有
socket
网络通信其实就是socket间的通信
数据在两个socket间通过io传输
传输协议不一样
/**
* Socket就是为
网络服务提供的一种机制
* 通信的两端都有Socket
* 网络通信其实就是Socket间的通信
* 数据在两个Socket间通过IO传输
* @author xinglefly
* @version 1
*/
public class UdpSend {
public static void main(String[] args) throws Exception{
/*1.找到对方ip
* 2.数据要发送到对方指定的应用程序上。
* 为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。
* 为了方便称呼这个数字,叫做端口。逻辑端口。
* 3.定义通信规则。这个通讯规则称为协议。
* 国际组织定义了通用协议TCP/IP
*/
/*需求:通过udp传输方式,将一段文字数据发送出去
* 思路:
* 1.建立updsocket服务
* 2.提供数据,并将数据封装到数据包中。
* 3.通过socket服务的发送功能,将数据包发出去。
* 4.关闭资源。
*/
//1.创建udp服务,通过DatagramSocket对象。
DatagramSocket ds = new DatagramSocket();
//2.确定数据,并封装成数据包。DatagramPacket(byte[] buf,int length,InetAddress address,int port)
byte [] by = "udp xuexi le ".getBytes();
DatagramPacket dp = new DatagramPacket(by,by.length,InetAddress.getByName("127.0.0.1"),10000);
//3.通过socket服务,将已有的数据包发送出去。通过send方法。
ds.send(dp);
//4.关闭资源。
ds.close();
}
}
/*
* 需求:定义一个应用程序,用于接收udp协议传输的数据并处理的
* 思路:
* 1.定义updsocket服务。通常会
监听一个端口。其实就是给这个接收网络应用程序定义数字标识
* 方便于明确哪些数据过来该应用程序可以处理。
* 2.定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多
* 功能可以提取字节数据中的不同数据信息。
* 3.通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
* 4.通过数据包对象的特有功能,将这些不同的数据取出。打印在控制台上。
* 5.关闭资源。
*/
class UdpRece{
public static void main(String[] args)throws Exception{
//1.创建udp socket,建立端点。
DatagramSocket ds = new DatagramSocket(10000);
//2.定义数据包,用于存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3.通过服务的receive方法将收到的数据存入数据包中。
ds.receive(dp);
//4.通过数据包的方法获取其中的数据
String ip = dp.getAddress().getHostAddress();
String data = new String (dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
ds.close();
}
}
package com.blackhorse.xinglefly;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* socket编程中的upd
* 需求:通过upd传输方式,将一段文字数据发送出去。
* 思路:
* 1.建立updsocket服务
* 2提供数据,并将数据封装成数据包中。
* 3.通过socket服务的发送功能,将数据包发出去
* 4.关闭资源
* @author xinglefly
* @version 1
*/
public class UpdSend {
public static void main(String[] args) throws Exception{
//1.创建upd服务,通过DatagramSocket对象
DatagramSocket ds = new DatagramSocket(8888);
//2.确定数据,并封装成数据包。DatagramPacket(byte[] buf,int length,InetAddress address,int port)
byte[] buf = "udp".getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.111.1"),1000);
//3.通过socket服务,将已有的数据包发送出去,通过send方法。
ds.send(dp);
//4.关闭资源
ds.close();
}
}
/**
* 需求:定义一个应用程序,用于接收udp协议传输的数据并处理的。
* 定义udp的接收端
* 思路:
* 1.定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。
* 方便于明确哪些数据过来该应用程序可以处理。
* 2.定义一个数据包,因为要存储接收到得字节数据。因为数据包对象中更多功能可以提取字节数据中的不同数据信息。
* 3.通过socket服务的receive方法将受到的数据存入已定义好的数据包中。
* 4.通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。
* 5.关闭资源。
* @author xinglefly
*
*/
class UpdRece{
public static void main(String[] args)throws Exception{
//1.创建upd socket,建立端点
DatagramSocket ds = new DatagramSocket(10000);
while(true){
//2.定义数据包,用于存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3.通过服务的receive方法将收到数据存入数据包中。
ds.receive(dp);//阻塞式方法
//4.通过数据包的方法获取其中的数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
}
//5.关闭资源
// ds.close();
}
}
/**
* 客户端
* 1.
服务端点
* 2.读取客户端已有的图片数据
* 3.通过socket输出流将数据发给服务端
* 4.读取服务端反馈信息
* 5.关闭
* @author xinglefly
* @version 1
*/
public class PicTest {
public static void main(String[] args)throws Exception{
if(args.length!=1){
System.out.println("请选择一个jpg格式的图片");
return ;
}
File file = new File(args[0]);
if(!(file.exists() && file.isFile())){
System.out.println("该文件有问题,要么不存在,要么不是文件");
return ;
}
if(!file.getName().endsWith(".jpg")){
System.out.println("图片格式
错误,请重新选择");
return ;
}
if(file.length()>1024*1024*5){
System.out.println("文件过大,请选择文件");
return ;
}
Socket s = new Socket("127.0.0.1",3330);
FileInputStream fis = new FileInputStream("c:\\001.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read())!=-1){
out.write(buf,0,len);
}
//告诉服务端数据已写完
s.shutdownOutput();
}
}
//
同步上传
//只要明确了每一个客户端要在服务端执行的代码即可。将代码存入run方法中。
class PicThread implements
Runnable{
private Socket s;
PicThread(Socket s){
this.s=s;
}
public void run(){
int count=1;
String ip = s.getInetAddress().getHostAddress();
try{
System.out.println(ip+"...conneted");
InputStream in = s.getInputStream();
File file = new File(ip+"("+(count)+")"+".jpg");
while(file.exists())
file = new File(ip+"("+(count++)+")"+".jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
}catch(Exception e){
throw new RuntimeException(e+"上传失败");
}
}
}
class PicServer{
public static void mian(String[] args)throws Exception{
/*ServerSocket ss = new ServerSocket(3330);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("c:\\server.jpg");
byte[] by = new byte[1024];
int len = 0;
while((len=in.read())!=-1){
fos.write(by,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
ss.close();*/
ServerSocket ss = new ServerSocket(3330);
while(true){
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
/**
* 编写一个
聊天程序
* 有收据的部分,和发行数据的不封
* 这两部分需要同时执行
* 那就需要用到多
线程技术
* 一个线程控制收,一个线程控制发
* 因为收和发动作是不一致的,所以要定义两个run方法。
* 而且这两个方法要封装在不同的类中。
* @author xinglefly
* @version 1
*/
class Send implements Runnable{
private DatagramSocket ds;
Send(DatagramSocket ds){
this.ds=ds;
}
public void run(){
BufferedReader br = null;
try{
br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=br.readLine())!=null){
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),1515);
ds.send(dp);
}
}catch(Exception e){
throw new RuntimeException("发送端失败");
}
}
}
class Rece implements Runnable{
private DatagramSocket ds;
Rece(DatagramSocket ds){
this.ds=ds;
}
public void run(){
try{
while(true){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
}
}catch(Exception e){
throw new RuntimeException("接收端失败");
}
}
}
public class ChatDemo {
public static void main(String[] args)throws Exception{
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket();
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}
import java.util.*;
import java.io.*;
import java.net.*;
/**
* 演示tcp的传输的客户端和服务端的互访。
* 需求:客户端给服务端发送数据,服务端收到后,给客户反馈信息。
* @author xinglefly
* @version 1
*/
public class TcpClient2 {
/*客户端
* 1.建立socket服务。指定要连接主机和端口。
* 2.获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
* 3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
* 4.关闭客户端资源。
*/
public static void main(String [] args)throws Exception{
Socket s = new Socket("127.0.0.1",3304);
OutputStream out = s.getOutputStream();
out.write("服务端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
import java.util.*;
import java.io.*;
import java.net.*;
/**
* 需求:建立一个文本转换服务器
* 客户端给服务端发送文本,服务端会将文本装换成大写在返回给客户端。
* 而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束。
* 分析:
* 客户端:
* 既然是操作
设备上的数据,那么就可以食用io技术,并按照io的操作规律来思考。
* 源:键盘录入。
* 目的:网络设备,网络输出流。
* 而且操作的是文本数据,可以选择字符流。
* 步骤:
* 1.建立服务
* 2.获取键盘录入
* 3.将数据发给服务端
* 4.后去服务端返回的大写数据。
* 5.结束,关资源。
* 都是文本数据,可以食用字符流进行操作,同事提高效率,加入缓冲。
* @author xinglefly
* @version 1
*/
public class TransClient {
public static void main(String[] args)throws Exception{
Socket s = new Socket("127.0.0.1",3300);
//定义读取键盘数据的流对象。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//定义目的,将数据写入到socket输出流,发给服务器
// BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//定义一个socket读取流,读取服务端返回的大写信息
BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
out.println(line);
/* bufout.write(line);
bufout.newLine();
bufout.flush();
*/ }
}
}
class TransSever{
public static void main(String[] args)throws Exception{
ServerSocket ss = new ServerSocket(3300);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
//读取socket读取流中的数据。
BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));
//目的。socket输出流,将大写数据写入到socket输出流,并发送给客户端。
// BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufin.readLine())!=null){
out.println(line);
/*bufout.write(line.toUpperCase());
bufout.newLine();
bufout.flush();*/
}
s.close();
ss.close();
}
}
/*该
例子出现的问题。
* 现象:客户端和服务端都在莫名的等待。
* 为什么呢?
* 因为客户端和服务端都有阻塞式方法。这些方法没有读到结束标记,那么就一直等
* 而导致两端都在等待。
*
*/