网络编程概述

------- android培训java培训、期待与您交流! ----------

1 网络模型:
1.1)OSI参考模型
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

1.2)TCP/IP参考模型
应用层               传输层 网际层     主机至网络层
网络通讯要素
1.2.1)ip地址
1.2.2)端口号  :数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识
端口一般是:0到6535,windows应用程序一般都占用了0到1024的端口
1.2.3)传输协议TCP和UDP协议

默认回环ip地址127.0.0.1   主机名:localhost
数据封包和数据拆包


/**
例子1:获取本机ip地址
*/
import java.net.*;
class IpDemo
{
	public static void main(String[] args)throws Exception
	{
	
	/*
	获取本机的ip地址和主机名,并返回ip对象
	InetAddress i=InetAddress.getLocalHost();
	
	System.out.println(i.toString());
	System.out.println("address"+i.getHostAddress());//本机的ip地址
	System.out.println("name"+i.getHostName());//主机名
	*/


	//输入主机名和ip地址都行,返回一个ip对象
	InetAddress ia=InetAddress.getByName("www.baibu.com");
	System.out.println(ia.toString());
	System.out.println("address"+ia.getHostAddress());//本机的ip地址
	System.out.println("name"+ia.getHostName());//主机名
	}
}

2 UDP
QQ聊天是UDP

2.1)udp特点

2.1.1)将数据及源和目的封装成数据包中,不需要建立链接
2.1.2)每个数据包的大小在限制64kb内
2.1.3)因无连接,是不可靠协议
2.1.4)不需要建立连接,速度快

3 TCP
电话是TCP
3.1)tcp特点
3.1.1)建立连接,形成传输数据的通道
3.1.2)在连接中进行大数据量传输
3.1.3)通过三次握手完成连接,是可靠协议
3.1.4)必须建立连接,效率会稍低

4 Socket
Socket就是为网络服务提供的一种机制
通讯的两端都有Socket
网络通讯其实就是Socket间的通信
数据在两个Socket间通过IO传输
注意:ip最后的数是0的表示是一个网址不能使用,是254的表示广播地址,如果定义这个地址发出去,只要端口对得上,都能接受到信息

/*    

需求:通过udp传输方式,将一段文字数据发送出去
思路:
1建立updsocket服务
2提供数据,并将数据封装到数据包中
3通过socket服务的发送功能,将数据包发出去
4关闭资源
*/
import java.net.*;
class UdpSend
{
	/*
	键盘录入
	public static void main(String[] args)throws Exception
	{

		//建立updsocket服务
		DatagramSocket ds=new DatagramSocket(1903);
		BufferedReader bur=new BufferedReader(new InputStreamReader(System.in));
		String line=null;
		while((line=bur.readLine())!=null)
		{
			if(line.equals("886"))
				break;
			byte[] buf=line.getBytes();
			DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.254"),10000);
	
			//提供数据,并将数据封装到数据包中DatagramPacket(byte[] buf,int length,InetAddress address,int port)
			//byte[] buf="udp ge men lai la".getBytes();
			//DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.84"),10000);
			//通过socket服务的发送功能,将数据包发出去
			ds.send(dp);
		}
		ds.close();
	}
	*/

	public static void main(String[] args)throws Exception
	{

		//建立updsocket服务
		DatagramSocket ds=new DatagramSocket(1903);

		//提供数据,并将数据封装到数据包中DatagramPacket(byte[] buf,int length,InetAddress address,int port)

		byte[] buf="udp ge men lai la".getBytes();
		DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.84"),10000);
		//通过socket服务的发送功能,将数据包发出去
		ds.send(dp);
		ds.close();
	}
}


/*
需求:定义一个应用程序,用于接受udp协议传输的数据并处理

思路:
1 定义udpsocket服务
2 定义一个数据包,因为要存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息
3 通过socket服务的receive方法将收到的数据存入已定义好的数据包中
4 通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上
5 关闭资源
*/


class UdpRece
{
	public static void main(String[] args)throws Exception
	{
	//创建udp socket,建立端点
	DatagramSocket ds=new DatagramSocket(10000);


	while(true)
	{
	//定义数据包,用于存储数据
	byte[] buf=new byte[1024];
	DatagramPacket dp=new DatagramPacket(buf,buf.length);


	//通过服务的receive方法将收到的数据存入数据包中
	ds.receive(dp);
	//通过数据包的方法获取其中的数据
	String ip=dp.getAddress().getHostAddress();
	//获取数据包中的数据:dp.getData()        数据的长度
	String data =new String(dp.getData(),0,dp.getLength());

	int port=dp.getPort();
	System.out.println(ip+"::"+data+"::"+port);


	//关闭资源
	//ds.close();
	}
	}
}

/*
这是一个聊天程序
*/


import java.io.*;
import java.net.*;


class UdpSend2 implements Runnable
{
	private DatagramSocket dgs;
	UdpSend2(DatagramSocket dgs)
	{
	this.dgs=dgs;
	}


	public void run()
	{
	try
	{
	//键盘录入
	BufferedReader bur=new BufferedReader(new InputStreamReader(System.in));


	String line=null;
	//读取键盘的数据
	while((line=bur.readLine())!=null)
	{
	if("886".equals(line)) //判断结束标记
	break;
	byte[] buf=line.getBytes();//把字符串转为字节数组
	
	//定义一个数据包,并把数据存储在包中
	DatagramPacket dgp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.254"),1003);


	dgs.send(dgp);//把数据包发送到指定的端口


	}
	dgs.close();//关闭资源
	}
	catch(Exception e)
	{
	throw new RuntimeException("发送失败");
	}
	}
}


class UdpRece2 implements Runnable 
{
	private DatagramSocket dgs;
	UdpRece2(DatagramSocket dgs)
	{
	this.dgs=dgs;
	}


	public void run()
	{
	while(true)
	{
	try
	{
	byte[] buf=new byte[1024];//定义数组
	//定义一个数据包
	DatagramPacket dgp=new DatagramPacket(buf,buf.length);


	dgs.receive(dgp);//接受端口发来的数据,存储在dgp包中,阻塞式语句


	String ip=dgp.getAddress().getHostAddress();//得到数据的ip地址
	//得到数据包中的内容
	String data=new String(dgp.getData(),dgp.getLength());
	//得到数据包的端口
	int port=dgp.getPort();


	System.out.println("ip:"+ip+"..."+"data:"+data+"port:"+port);
	}


	catch(Exception e)
	{
	throw new RuntimeException("接受信息失败");
	}
	}
	}
}


class UdpDemo
{
	public static void main(String[] args)throws Exception
	{
	DatagramSocket send=new DatagramSocket();
	DatagramSocket rece=new DatagramSocket(1003);//指定端口


	UdpSend2 usend=new UdpSend2(send);
	UdpRece2 urece=new UdpRece2(rece);
	//开启线程
	new Thread(usend).start();
	new Thread(urece).start();
	}
}

4.1 TCP
4.1.1) tcp分客户端和服务端
4.1.2) 客户端对应的对象是Socket
4.1.3)服务器对应的对象是ServerSocket

客户端:
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机
因为tcp是面向连接的,所以在建立socket服务时
就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输

步骤:
1 创建Socket服务,并指定要连接的主机和端口
2 获取对应的输出流对象

3 向流中写入东西

/*
例子:演示tcp传输
*/
import java.io.*;
import java.net.*;
class TcpClient
{
	public static void main(String[] args)throws Exception
	{
	//创建客户端的socket服务,指定目的主机和端口
	Socket s=new Socket("169.254.0.84",1003);


	//为了发送数据,应该获取socket流中的输出流
	OutputStream out=s.getOutputStream();


	out.write("tcp ge men lai la".getBytes());


	s.close();
	}
}

/*
需求:定义TCP传输,定义端点接收数据并打印在控制台上

服务台:
1 建立服务端的socket服务.  SeverSocket();并监听一个端口
2 获取连接过来的客户端对象
  通过ServerSocket的accept方法,没有连接就会等,所以这个方法是阻塞式的
3 客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台
4 关闭服务端(可选)

*/


class TcpServer
{
	public static void main(String[] args)throws Exception
	{
	//建立服务端socket服务,并监听一个端口
	ServerSocket ss=new ServerSocket(1003);


	//通过accept方法获取连接过来的客户端对象
	Socket s=ss.accept();


	//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据
	InputStream in=s.getInputStream();


	byte[] buf=new byte[1024];
	int len=in.read(buf);
	
	System.out.println(new String(buf,0,len));


	s.close();//关闭客户端
	ss.close();
	}
}

/*
例子:键盘录入数据,把数据传到网络流中,客户端读取键盘录入的数据,写到网络流中,服务端把客户端的数据返回大写,客户端读取到服务端返回的数据
*/


import java.io.*;
import java.net.*;
class Socket3
{
	public static void main(String[] args)throws Exception
	{
	Socket s=new Socket("169.254.0.84",1005);


	BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));


	BufferedWriter bfwout=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));


	BufferedReader bfrin=new BufferedReader(new InputStreamReader(s.getInputStream()));


	String line=null;
	while((line=bfr.readLine())!=null)
	{
	if("over".equals(line))
	break;


	bfwout.write(line);
	bfwout.newLine();
	bfwout.flush();
	
	String str=null;
	str=bfrin.readLine();
	System.out.println(str);
	
	}
	
	
	s.close();
	bfr.close();
	}
}




class ServerSocket3
{
	public static void main(String[] args)throws Exception
	{
	ServerSocket ss=new ServerSocket(1005);


	Socket s=ss.accept();
	String ip=s.getInetAddress().getHostAddress();
	System.out.println(ip+"connect...");	


	BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));


	BufferedWriter bufout=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));


	String line=null;
	while((line=bufin.readLine())!=null)
	{
	System.out.println(line);
	bufout.write(line.toUpperCase());
	bufout.newLine();
	bufout.flush();
	}


	s.close();
	ss.close();
	}
}

注意:s.shutdownOutput();给输出流加上加上结束标记
/*
上传图片到服务器
*/

import java.io.*;
import java.net.*;
class PicClient
{
	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("该文件有问题,要么不存在,要么不是文件");
	}


	if(!file.getName().endsWith(".jpg"))
	{
	System.out.println("图片格式错误,请重新选择");
	}


	if(file.length()>1024*1024*5)
	{
	System.out.println("图片过大,没安好心");
	}


	Socket s=new Socket("169.254.0.84",1006);
	
	FileInputStream fis=new FileInputStream(file);
	InputStream fisin=s.getInputStream();
	OutputStream fosout=s.getOutputStream();




	byte[] buf=new byte[1024];
	int len=0;


	while((len=fis.read(buf))!=-1)
	{
	fosout.write(buf,0,len);
	}
	s.shutdownOutput();


	byte[] buf2=new byte[1024];
	int len2=0;
	len2=fisin.read(buf2);
	System.out.println(new String(buf2,0,len2));


	fis.close();
	s.close();
	}
}


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("connect..."+ip);
	


	File file=new File(ip+"("+(count)+")"+".jpg");
	while(file.exists())
	file=new File(ip+"("+(count++)+")"+".jpg");




	FileOutputStream fos=new FileOutputStream(file);
	InputStream fisin=s.getInputStream();


	byte[] buf=new byte[1024];
	int len=0;


	while((len=fisin.read(buf))!=-1)
	{
	fos.write(buf,0,len);
	}


	OutputStream fosout=s.getOutputStream();
	fosout.write("上传图片成功".getBytes());


	fos.close();
	s.close();
	}


	catch(Exception e)
	{
	throw new RuntimeException("文件上传失败");
	}
	}
}


class PicServer
{
	public static void main(String[] args)throws Exception
	{
	ServerSocket ss=new ServerSocket(1006);
	while(true)
	{
	Socket s=ss.accept();
	new Thread(new PicThread(s)).start();
	}
		
	//ss.close();
	}
}

5 浏览器上的地址一般都是主机名但是socket是地址名,所以他要进行域名解析,找公网的dns服务器,里面都有主机和ip地址的映射表关系,解析完返回来,拿到ip地址再去访问网站
先走本地的host文件,再走公网的DNS服务器
这时候我们就有搞头了!
127.0.0.1是回环地址,是访问本机的,一个地址可以对应多个主机名
  1一些恶意网站可以设置:主机名的地址映射关系是127.0.0.1这样它就访问不了恶意网站了
  2一些使用软件,要输入注册码,输入注册码的时候它会连接到网站进行更新,可以作上述设置,让他更新失败
  3把常用的网址在本地进行映射,以加快速度




 ------- android培训java培训、期待与您交流! ----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值