黑马程序员 网络编程

                                          黑马程序员网络编程

  ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

1.网络模型

(1)OSI参考模型

(2)TCP/IP参考模型



2.网络通讯要素

(1)IP地址

(a)网络中设备的标识

(b)不易记忆,可用主机名

(c)本地回环地址:127.0.0.1 主机名:localhost

(2)端口号

(a)数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,叫做逻辑端口。

(b)用于标识进程的逻辑地址,不同进程的标识。

(c)有效端口:0~55535,其中0~1024系统使用或保留端口。

(3)传输协议:通信规则,国际组织定义了通用协议TCP/IP.常见的协议还有UDP


3.获取IP地址对象

(1)获取本机IP地址对象:InetAddress i=InetAddress.getLocalHost();返回一个本机IP地址对象。

(2)i.getHostAddress();获取本机IP地址,i.getHostName();获取本机主机名。

(3)获取其他机的IP地址对象:

InetAddress ia=InetAddress.getByName(“www.baidu.com”);返回其他机的IP地址对象。

(4)获取其他机对应的地址值:ia.getHostAddress();

(5)获取其他机对应的主机名:ia.getHostName();


4.TCP

(1)建立连接,形成传输数据的通道。

(2)在连接中进行大数据量传输

(3)通过三次握手完成连接,是可靠协议

(4)必须建立连接,效率会稍低。


5.UDP

(1)将数据及源和目的封装成数据包中,不需要建立连接

(2)每个数据报的大小在限制在64K内

(3)因无连接,是不可靠协议

(4)不需要建立连接,速度快


6.Socket

(1)Socket就是为网络服务提供的一种机制

(2)通信的两端都有Socket

(3)网络通信其实就是Socket间的通信

(4)数据在两个Socket间通过IO传输。


7.UDP传输

(1)DatagramSocket与DatagramPacket

(2)建立发送端,接收端。

(3)建立数据包。

(4)调用Socket的发送接收方法。

(5)关闭Socket。

(6)发送端与接收端是两个独立的运行程序。

/*
需求:通过udp传输方式,将一段文字数据发送出去。
思路:
1.建立udp socket服务
2.提供数据,并将数据封装到数据包中。
3.通过socket服务的发送功能,将数据包发出去。
4.关闭资源。
*/
import java.net.*;
class UdpSend 
{
	public static void main(String[] args) throws Exception
	{
		//创建udp服务,通过DatagramSocket对象。
		DatagramSocket ds=new DatagramSocket(8888);
		//确定数据,并封装成数据包。DatagramPacket(byte[] buf,int length,InetAddress address,int port)
		byte[] buf="udp ge men lai le".getBytes();
		DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
		//通过socket服务,将已有的数据包发送出去,通过send方法。
		ds.send(dp);
		//关闭资源
		ds.close();
	}
}
/*
定义一个应用程序,用于接收udp协议传输的数据并处理的
思路:
1.定义udpsocket服务。
2.定义一个数据包,因为要存储接收到的字节数据。因为
数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3.通过socket服务的receive方法将接收到的数据存入已定义好的数据包中。
4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上。
5.关闭资源。
*/
import java.net.*;
class  UdpRece
{
	public static void main(String[] args) throws Exception
	{
		//创建udp socket,建立端点
		DatagramSocket ds=new DatagramSocket(10000);
		//定义数据包,用于存储数据。
		byte[] buf=new byte[1024];
		DatagramPacket dp=new DatagramPacket(buf,buf.length);
		//通过服务的receive方法将收到数据存入数据包中。
		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);
		//关闭资源
		ds.close();
	}
}

8.Udp-键盘录入数据方式练习

import java.net.*;
import java.io.*;
//发送端
class UdpSend2
{
	public static void main(String[] args) throws Exception
	{
		DatagramSocket ds=new DatagramSocket();//创建端口
		BufferedReader bufr=
			new BufferedReader(new InputStreamReader(System.in));//创建读取流
		String line=null;
		//将每行数据转成字节数据存到字节数组buf里
		while((line=bufr.readLine())!=null)
		{
			if("886".equals(line))
				break;
			byte[] buf=line.getBytes();
			//再把字节数据封装到包里面
			DatagramPacket dp=
				new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.101"),10001);
			ds.send(dp);//发送
		}
		ds.close();//关闭端口
	}
}
class UdpRece2  
{
	public static void main(String[] args) throws Exception
	{
		DatagramSocket ds=new DatagramSocket(10001);//创建端口
		while(true)
		{
			byte[] buf=new byte[1024];//创建字节数组接受字节数据
			//创建数据包将buf里的数据封装到包里面
			DatagramPacket dp=new DatagramPacket(buf,buf.length);
			ds.receive(dp);//有数据就接收,没数据就wait
			String ip=dp.getAddress().getHostAddress();//获取IP
			String data=new String(dp.getData(),0,dp.getLength());//获取数据
			System.out.println(ip+"::"+data);
		}
	}
}

9.编写一个聊天程序:

/*
编写一个聊天程序
有收数据的部分和发数据的部分,
这两部分需要同时执行,
那就需要用到多线程技术,
一个纯种控制收,一个线程控制发。
因为收和发动作不一致,所以定义两个run方法。
而且这两个方法要封装到不同的类中
*/
import java.io.*;
import java.net.*;

class Send implements Runnable
{
	private DatagramSocket ds;
	public Send(DatagramSocket ds)
	{
		this.ds=ds;
	}
	public void run()//覆写Runnable的run方法
	{
		try
		{
			//创建读取流对象读取键盘录入
			BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
			String line=null;
			while((line=bufr.readLine())!=null)
			{
				//如果输入"886"则跳出循环
				if("886".equals(line))
					break;
				byte[] buf=line.getBytes();
				//将数据封装成数据包
				DatagramPacket dp=
					new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.101"),10002);
				ds.send(dp);//发送
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException("发送端失败");
		}
	}
}
class Rece implements Runnable
{
	private DatagramSocket ds;
	public 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();//获取IP地址值
				String data=new String(dp.getData(),0,dp.getLength());
				System.out.println(ip+"::"+data);
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException("接收端失败");
		}
	}
}
class  ChatDemo
{
	public static void main(String[] args) throws Exception
	{
		//创建发送和接收端口
		DatagramSocket sendSocket=new DatagramSocket();
		DatagramSocket receSocket=new DatagramSocket(10002);
		//创建两个线程对象并启动
		new Thread(new Send(sendSocket)).start();
		new Thread(new Rece(receSocket)).start();
	}
}

10.TCP传输

(1)SocketServerSocket

(2)建立客户端和服务器端

(3)建立连接后,通过Socket中的IO流进行数据的传输

(4)关闭socket

(5)同样,客户端与服务器端是两独立的应用程序

/*
需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端,
而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束。
分析:
客户端:既然是操作设备上的数据,那么就可以使用io技术,
并按照io的操作规律来思考。
源:键盘录入。
目的:网络设备,网络输出流。
而且操作的是文本数据,可以选择字符流。
步骤:
1.建立服务。
2.获取键盘录入。
3.将数据发给服务端。
4.服务端返回的大写数据。
5.结束,关闭资源。
*/
import java.io.*;
import java.net.*;
class TransClient
{
	public static void main(String[] args) throws Exception
	{
		Socket s=new Socket("192.168.1.101",10005);
		//定义读取键盘数据的流对象。
		BufferedReader bufr=
			new BufferedReader(new InputStreamReader(System.in));
		//定义目的,将数据写入到socket输出流,发给服务端。
		BufferedWriter bufOut=
			new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		//定义一个socket读取流,读取服务端返回的大写信息
		BufferedReader bufIn=
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		String line=null;
		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bufOut.write(line);
			bufOut.newLine();//换行
			bufOut.flush();		
			String str=bufIn.readLine();
			System.out.println("server:"+str);

		}
	}
}
class  TranServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss=new ServerSocket(10005);
		Socket s=ss.accept();
		String ip=s.getInetAddress().getHostAddress();
		System.out.println(ip+"...connected");
		//读取socker读取流中的数据
		BufferedReader bufIn=
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		//目的,socket输出流,将大写数据写到socket输出流,并发送给客户端。
		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();
	}
}

11.

//TCP复制文件
import java.io.*;
import java.net.*;
class TextClient
{
	public static void main(String[] args) throws Exception
	{
		Socket s=new Socket("10.220.162.56",10006);//创建客户端端口
		//创建一个读取流对象,读取一个文本数据
		BufferedReader buffr=new BufferedReader(new FileReader("net.txt"));
		//获取Socket输出流,将文本内容发给服务端。此输出流可以自动刷新和换行
		PrintWriter out =new PrintWriter(s.getOutputStream(),true);
		String line=null;
		while((line=buffr.readLine())!=null)
		{
			out.println(line);
		}
		s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入一个结束标记-1
		//获取Socket输入流对象,将读取socket输入流数据
		BufferedReader bufIn=
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		String str=bufIn.readLine();
		System.out.println(str);
		buffr.close();
		s.close();
	}
} 

class TextServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss=new ServerSocket(10006);//创建服务端端口
		Socket s=ss.accept();//连接
		String ip=s.getInetAddress().getHostAddress();//获取IP地址值
		System.out.println(ip+"........connected");
		//获取Socket中的读取流,读取客户端发过来的数据
		BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream()));
		//创建写入流,将读取到的数据写到文本中
		PrintWriter out=new PrintWriter(new FileWriter("server.txt"),true);
		String line=null;
		while((line=bufIn.readLine())!=null)
		{
			out.println(line);
		}
		//获取Socket中的输出流,给客户端反馈信息
		PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
		pw.println("上传成功");
		out.close();
		s.close();
		ss.close();
	}
}

12.

//TCP-客户端并发上传图片
import java.io.*;
import java.net.*;

class PicClient
{
	public static void main(String[] args) throws Exception
	{
		//运行时要添加上传的图片,如:java PicClient e:\1.jpg
		if(args.length!=1)
		{
			System.out.println("请选择一个jpg格式的图片");
			return;
		}
		//判断要上传的图片是否存在
		File file=new File(args[0]);
		if(!(file.exists() && file.isFile()))
		{
			System.out.println("该文件有问题,要么不存在,要么不是文件");
			return;
		}
		//判断格式是否为jpg
		if(!file.getName().endsWith(".jpg"))
		{
			System.out.println("图片模式错误,请重新选择");
			return;
		}
		//上传的图片不能超过5M
		if(file.length()>1024*1024*5)
		{
			System.out.println("图片过大");
			return;
		}

		Socket s=new Socket("192.168.1.106",10007);//创建客户端端口
		FileInputStream fis=new FileInputStream(file);//创建字节读取流对象读取图片
		OutputStream out=s.getOutputStream();//获取Socket中的输出流对象
		byte[] buf=new byte[1024];
		int len=0;
		while((len=fis.read(buf))!=-1)
		{
			out.write(buf,0,len);
		}
		//告诉服务端数据已写完
		s.shutdownOutput();
		//获取Socket中的读取流对象
		InputStream in=s.getInputStream();
		byte[] bufIn=new byte[1024];
		int num=in.read(bufIn);
		System.out.println(new String(bufIn,0,num));
		fis.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();//获取IP地址值
		try
		{
			
			System.out.println(ip+"........connected");
			//获取Socket读取流对象
			InputStream in=s.getInputStream();
			//用IP地址值和编号作为文件名
			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);
			}
			//获取Socket输出流,给客户端反馈信息
			OutputStream out=s.getOutputStream();
			out.write("上传成功".getBytes());
			fos.close();
			s.close();

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


class PicServer
{
	public static void main(String[] agrs) throws Exception
	{
		ServerSocket ss=new ServerSocket(10007);//创建服务端端口
		while(true)
		{
			Socket s=ss.accept();
			new Thread(new PicThread(s)).start();//创建线程并启动线程
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值