JAVA基础---网路编程---概述,UDP/TCP对应Socket,小知识点

第一讲. 概述

网络通信要素:IP(本地回环地址 127.0.0.1 ,主机名localhost), 端口(0~65535),  协议

网络层次:OSI参考模型,7层参考模型;TCP/IP的参考模型:应用层(如 http),传输层(如 TCP),网际层(如 IP),主机至网络层

两大传输协议:

UDP(好比:步话机)TCP(好比:打电话)
  1. 将数据及源和目的封装成数据包,不需要建立连接
  2. 数据包的大小限制在64k内
  3. 因无连接,是不可靠传输
  4. 速度快
  5. 适用:聊天,视频会议,桌面共享
  1. 建立连接,形成数据传输的通道
  2. 在连接中进行大数据量传输
  3. 通过三次握手完成连接,是可靠协议
  4. 必须建立连接,效率稍低

  1. Java中的ip对象  InetAddress,单例设计模式,通过getLocalHosh(),getByAddress(),getByName()等方法获得实例对象
  2. socket 套接字 ,Java靠Socket完成网络的传输层通信,即收发数据包。

第二讲. DatagramSocket   :UDP的Socket

  1.  *.*.*.255是广播地址,*.*.*.0代表一个网络段
  2. 由于端口可能还未释放,反复运行发送程序系统会自动顺延端口号,当然也可以指定发送端口
  3. 定义udp接受端时,需要监听某一个端口,其实就是给这个接收网络应用程序定义一个数字标识
  4. 重复new Socket会发生BindExcepiton 重复绑定异常
    import java.net.*;
    import java.io.*;
    class  UDPSend
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket();
    		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    		while(true){
    			String line = in.readLine();//阻塞式方法
    			if("886".equals(line))
    				break;
    			byte[] data = line.getBytes();
    			//构造方法为:DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
    			DatagramPacket dp = new DatagramPacket
    				(data,data.length,InetAddress.getByName("59.66.201.255"),50000);//广播地址
    			ds.send(dp);
    		}
    		in.close();
    		ds.close();//端口可能还未释放,反复运行发送程序系统会自动顺延端口号
    	}
    }
    
    class UDPReceive
    {
    	public static void main(String[] args) throws Exception
    	{
    		DatagramSocket ds = new DatagramSocket(50000);
    		while(true){
    			//DatagramSocket ds = new DatagramSocket(50000); // BindException重复绑定异常
    			byte[] buff = new byte[1024];
    			DatagramPacket dp = new DatagramPacket(buff,buff.length);
    			ds.receive(dp);//阻塞式的方法
    			
    			String ip = dp.getAddress().getHostAddress();
    			String data =new String(dp.getData(),0,dp.getLength());
    			System.out.println("ip::"+ip+"\tdata::"+data);
    			System.out.println(dp.getPort());
    		}
    		//ds.close();
    	}
    }

第三讲. Scoket,ServerSocket :TCP的套接字对象

  1. Socket:在建立时就可以连接主机,因为TCP是面向连接的
  2. ServerSocket:服务端,建立是要绑定端口,通过accept阻塞式方法接收客户端socket对象
  3. 现象:客户端和服务端都在莫名的等待。 原因:两端的阻塞式方法未读到结束标志。
    /*从客服端的键盘录入文本数据。服务器接收到数据,转化为大写并转发回客户端。客户端将其打印到控制台上*/
    import java.io.*;
    import java.net.*;
    class  TcpClient
    {
    	public static void main(String[] args) throws Exception
    	{
    		BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    		String line;
    		while(!((line=input.readLine()).equals("over")))
    		{
    			Socket socket = new Socket("127.0.0.1",50000);
    			PrintWriter out = new PrintWriter(socket.getOutputStream(),true);//这里必须autoflush
    			out.println(line);
    			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    			String data = in.readLine();
    			System.out.println("从服务端转发来的大写数据:"+data);
    			socket.close();
    		}
    	}
    }
    class TcpServer
    {
    	public static void main(String[] args) throws Exception
    	{	
    		ServerSocket ss = new ServerSocket(50000);
    		while(true){
    			Socket s = ss.accept();
    			String ip = s.getInetAddress().getHostAddress();
    			System.out.println("ip::"+ip);
    			BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
    			String data = (in.readLine()).toUpperCase();
    			PrintWriter out = new PrintWriter(s.getOutputStream(),true);
    			out.println(data);
    			s.close(); //在服务器端必须关闭Socket以断开客服端连接
    		}
    	}
    }

练习:复制文本文件,Socket中shutdownOutputStream()方法的应用:写入结束符。

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

class TextClient
{
	public static void main(String[] args) throws Exception
	{
		BufferedReader in = new BufferedReader(new FileReader("TCPDemo.java"));
		Socket s = new Socket("127.0.0.1",50000);
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		String line;
		while((line=in.readLine())!=null){
			out.println(line);
		}
		s.shutdownOutput();//out.println("over");
		s.close();
	}
}
class TextServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(50000);
		while(true)
		{
			Socket s = ss.accept();
			BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			PrintWriter out = new PrintWriter("TCPDemo.txt");
			String line;
			while((line=in.readLine())!=null){
				out.println(line);
			}
			out.close();
			s.close();
			System.out.println("文件复制成功!");
		}
	}
}

练习:服务端多线程,实现并发登陆

/***客户端通过键盘录入用户名,服务端进行校验
	如果用户存在,服务端显示XXX,已登陆;客户端显示XXX,欢迎光临
	如果不存在,服务端显示XXX,尝试登陆;客户端显示XXX,用户不存在,最多校验三次 
**/
import java.net.*;
import java.io.*;
class ClientThread implements Runnable
{
	private Socket s;
	ClientThread(Socket s){this.s = s;}
	private boolean checkName(String name) throws IOException
	{
		BufferedReader in = new BufferedReader(new FileReader("Logname.txt"));
		String line;
		while((line = in.readLine())!=null)
			if(line.equals(name)) return true;
		return false;
	}
	public void run(){
		int count = 3;//设置重复校验次数
		try
		{
			BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			PrintWriter out = new PrintWriter(s.getOutputStream(),true);
			while((count--)!=0){
				String name = in.readLine();
				if(checkName(name)){
					System.out.println(name+",已登陆");
					out.println(name+",欢迎光临");
					return;
				}
				else{
					System.out.println(name+",尝试登陆");
					out.println(name+",该用户不存在");
				}
			}
			s.shutdownOutput();
			s.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException("登陆异常!");
		}
	}
}
class  LoginClient//客户端
{
	public static void main(String[] args) throws Exception
	{
		Socket s = new Socket("127.0.0.1",20000);
		BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
		BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		String line,name;
		while(true){
			System.out.println("请输入登陆名:");
			name = input.readLine();
			out.println(name);
			line = in.readLine();
			if(line==null)  break;
			else if(line.equals(name+",欢迎光临"))
			{
				System.out.println(line);
				break;
			}
			else  System.out.println(line);
		}
		input.close();
		s.close();
	}
}
class  LoginServer//服务端
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(20000);
		while(true){	
			Socket s = ss.accept();
			new Thread(new ClientThread(s)).start();//为新加入的客户创建线程
		}
	}
}

第四讲. 小知识点
  1. InetAddress类是对IP地址的封装。
  2. Socke的connect(SocketAddress endpoint)方法中,SocketAddress 叫做套接字地址,是抽象对象。其子类InetSocketAddress,实现了(IP地址+端口号)的封装。
  3. ServerSocket的构造方法 ServerSocket(int port, int backlog)中的int backlog指的是指定服务端最大连接数,限定了同时在线的客户数。
  4. URL 代表一个统一资源定位符,它是指向互联网“资源”的指针(就是封装了域名)。URI类代表一个统一资源标识符 (URI) 引用(比URL范畴广一点)。URL的openConnecton()方法返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接(在应用层上的网络连接,里面封装了Socket,好处是去掉了http等应用层协议的消息头,只保留消息主体)。
  5. 域名解析:就是把域名(主机名)演绎成IP地址,即DNS(DomainNNameSystem)。先找本地的hosts文件中查找,再在配置中指定的DNS服务器去解析域名。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值