java网络编程

底层

概念

将不同区域的计算机连接在一起

局域网,城域网,广域网,互联网

地址

IP地址确定网络上的一个绝对地址(房子地址)

端口号

区分计算机软件 2个字节 0-65535bit (房间号)

在同一个协议下,端口号不能重复

1024以下的端口不能使用,80 http,21 ftp

资源定位

URL 统一资源定位符

URI 统一资源

##数据的传输

###协议

TCP:transfer control protocol 类似于三次握手,面向连接,安全可靠,效率低下

UDP:user datagram protocol 非面向连接,数据可重发

###传输

先封装,后拆封

InetAddress,InetSocketAddress

URL

TCP:ServerSocket,Socket

UDP:DatagreamSocket,DatagramPacket

InetAddress

封装计算机的IP地址和DNS,没有端口

			System.out.println("通过getLocalHost()创建InetAddress对象");
			InetAddress address = InetAddress.getLocalHost(); 
			System.out.println(address.getHostName()); 
			System.out.println(address.getHostAddress());
			
			System.out.println("通过域名得到InetAddress对象");
			address = InetAddress.getByName("www.baidu.com");
			System.out.println(address.getHostName());
			System.out.println(address.getHostAddress());
			
			address = InetAddress.getByName("123.56.138.186");
			System.out.println("IP不存在/DNS不可解析时返回IP");
			System.out.println(address.getHostName());

InetSocketAddress

在InetAddress基础上,包含端口,用于Socket通信

//new InetSocketAddress(String hostname, port);
		//new InetSocketAddress(InetAddress, port);
		InetSocketAddress socket = new InetSocketAddress("localhost", 8080);
		System.out.println(socket.getPort());
		System.out.println(socket.getAddress());//InetAddress
		System.out.println(socket.getHostName());

URI

统一资源标识符

URL

统一资源定位器 — 指向互联网资源的指针

https://www.baidu.com:80/Index.html?u=bjsxt#aa
协议域名端口资源文件名锚点锚点
			URL url = new URL("https://www.baidu.com:80/index.html?uname=bjsxt#a");
			System.out.println("协议 "+url.getProtocol());
			System.out.println("域名 "+url.getHost());
			System.out.println("端口 "+url.getPort());
			System.out.println("资源 "+url.getFile());
			System.out.println("路径 "+url.getPath());
			System.out.println("锚点 "+url.getRef());
			System.out.println("参数 "+url.getQuery());

####网络爬虫

URL url = new URL("https://www.dianping.com");
			
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("User-Agent", "...");
			
reader  = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));

write = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("src/files/baidu.html")),"UTF-8"));
			char[] flush = new char[512];
			int len = -1;
			while((len=reader.read(flush))!=-1) {
				write.write(flush,0,len);
			}
			write.flush();

UDP

UDP:user datagram protocol 非面向连接,数据可重发

public class UDPServer {

	public static void main(String[] args) {
		DataInputStream in = null;
		try {
			
			//创建对象
			DatagramSocket server = new DatagramSocket(6666);
			
			//接受数据
			byte[] container = new byte[1024];
			DatagramPacket packet = new DatagramPacket(container,container.length);
			server.receive(packet);
			
			//打印数据
			byte[] data = packet.getData();
			int len = packet.getLength();
			in = new DataInputStream(new ByteArrayInputStream(data));
			String str= in.readUTF();
			System.out.println(str);
			
			//释放资源
			server.close();
			
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(in!=null)
			{
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
  }
}



public class UDPClient {

	public static void main(String[] args) {
		ByteArrayOutputStream byteOut = null;
		DataOutputStream out = null;
		try {
			//创建对象
			DatagramSocket client = new DatagramSocket(8888);
			
			byteOut = new ByteArrayOutputStream();
			out = new DataOutputStream(byteOut);
			
			String str = "Hello World";
			out.writeUTF(str);
			out.flush();
			
			byte[] data = byteOut.toByteArray();
			//打包数据
			DatagramPacket pocket = new DatagramPacket(data, data.length, new InetSocketAddress("localhost",6666));
			
			//发送数据
			client.send(pocket);
			
			//释放资源
			client.close();
			
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(out!=null)
			{
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(byteOut!=null)
			{
				try {
					byteOut.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

TCP

TCP:transfer control protocol 类似于三次握手,面向连接,安全可靠,效率低下

//服务端
//指定端口
ServerSocket server = new ServerSocket(8888);
//接收客户端连接
Socket s = server.accept();
//发送数据
DataOutputStream data = new DataOutputStream(s.getOutputStream());
data.writeUTF("你好");
data.flush();

//客户端
//指定服务器+端口
Socket client = new Socket("localhost",8888);
//接收数据
DataInputStream in = new DataInputStream(client.getInputStream());
String str = in.readUTF();
System.out.println(str);
client.close();
QQ
//服务器
public class ServerSocketTest{

	private ServerSocket server = null;
	private CopyOnWriteArrayList<MyChannel> all = new CopyOnWriteArrayList<>();

	private void start()
	{
		try {
			server = new ServerSocket(8888);
			while(true)
			{
				Socket client = server.accept();
				MyChannel channel = new MyChannel(client);
				all.add(channel);
				new Thread(channel).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args) {
		new ServerSocketTest().start();
	}
	
	private class MyChannel implements Runnable{

		private DataOutputStream sendData = null;
		private DataInputStream receiveData = null;
		private boolean isRunning = true;
		private String name="";
		
		public MyChannel(Socket client)
		{
			try {
				sendData = new DataOutputStream(client.getOutputStream());
				receiveData = new DataInputStream(client.getInputStream());
				this.name=receiveData.readUTF();
				this.send("欢迎"+this.name+"加入聊天室,当前聊天室人数 "+(all.size()+1);
				this.sendOther(this.name+"进入聊天室", true);
			} catch (IOException e) {
				e.printStackTrace();
			}		
		}
		
		private void send(String s)
		{
			try {
				sendData.writeUTF(s);
				sendData.flush();
			} catch (IOException e) {
				e.printStackTrace();
				isRunning = false;
				all.remove(this);
				this.sendOther(this.name+"已退出群聊",true);
				FileUtil.close(receiveData,sendData,server);
			}	
		}
		
		private String receive()
		{
			String str=null;
			try {
				str=receiveData.readUTF();
			} catch (IOException e) {
				e.printStackTrace();
				isRunning = false;
				all.remove(this);
				this.sendOther(this.name+"已退出群聊",true);
				FileUtil.close(receiveData,sendData,server);
			} 
			return str;
		}
		public void sendOther(String msg,boolean flag)
		{
			if(msg.startsWith("@")&&msg.indexOf(":")>-1)
			{
				String name = msg.substring(1,msg.indexOf(":"));
				String content = msg.substring(msg.indexOf(":")+1);
				
				for(MyChannel other:all)
				{
					if(other.name.equals(name))
					{
						other.send(this.name+" 对您悄悄地说 "+content);
					}
				}
			}else {
				for(MyChannel other:all)
				{
					if(other==this)
					{
						continue;
					}
					if(flag){
						other.send("系统信息 " + msg);
					}
					else {
						other.send(this.name +" 对所有人说 " + msg);	
					}
				}
			}
		}
		@Override
		public void run() {
			
			while(isRunning)
			{
				this.sendOther(this.receive(), true);
			}
		}
	}
}

//客户端
public class SocketTest{
	
	private Socket client = null;
	private BufferedReader sendReader = null;
	private String name;
	public void start() {
		try
		{
			client = new Socket("localhost",8888);
			sendReader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
			name = sendReader.readLine();
			new Thread(new SendQQ(name,client)).start();
			new Thread(new ReceiveQQ(client)).start();
		}catch (IOException e) {
			e.printStackTrace();
		}	
	}
	public static void main(String[] args) {
		new SocketTest().start();
	}
}
//发送并发
public class SendQQ implements Runnable {

	private BufferedReader sendReader = null;
	private DataOutputStream sendData = null;
	
	private boolean isRunning = true;
	private Socket client=null;
	
	
	public SendQQ(String name, Socket client) {
		this.client=client;
		try {
			sendReader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
			sendData = new DataOutputStream(client.getOutputStream());
			this.send(name);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	private String getMsgFromConsole()
	{
		String str=null;
		try {
			str=sendReader.readLine();
			
		} catch (IOException e) {
			e.printStackTrace();
			isRunning=false;
			FileUtil.close(sendData,sendReader,client);
			
		} 
		return str;
	}
	private void send(String msg)
	{
		if(msg!=null&&!msg.equals(""))
		{
			try {
				sendData.writeUTF(msg);
				sendData.flush();
			} catch (IOException e) {
				e.printStackTrace();
				isRunning=false;
				FileUtil.close(sendData,sendReader,client);
			}		
		}
	}
	@Override
	public void run() {
		while(isRunning)
		{
			send(getMsgFromConsole());
		}
	}
}
//接收并发
public class ReceiveQQ implements Runnable {
	
	private boolean isRunning = true;

	private DataInputStream receiveData = null;
	
	private Socket client=null;
	
	public ReceiveQQ(Socket client)
	{
		this.client=client;
		try {
			receiveData = new DataInputStream(client.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private String receive()
	{
		String str=null;
		try {
			str=receiveData.readUTF();
		} catch (IOException e) {
			e.printStackTrace();
			isRunning = false;
			FileUtil.close(receiveData,client);
		} 
		return str;
	}
	@Override
	public void run() {
		while(isRunning)
		{
			System.out.println(this.receive());
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值