网络编程基础

网络编程

目的

直接或间接地通过网络协议与其它计算机进行通讯

想要编写网络程序时所面临的问题

  1. 如何准确地定位网络上一台或多台主机

  2. 找到主机后如何可靠高效地进行数据传输

几个概念

计算机网络(Network):就是将地理位置不同的网络终端设备,通过网络传输介质连接起来,在网络操作系统和网络通信协议的管理和协调下,实现资源共享和信息传递的功能。
IP 地址(Internet Protocol Address):是互联网协议特有的一种地址。它是一台终端设备在网络中的唯一标识
	IP地址有两种分类:IPv4(4个单字节无符号数字排列组合形成的唯一标识) 和 IPv6(8个16位的16进制无符号数字排列组合形成的唯一标识)
	本地自回环网络标识:127.0.0.1, 网络名是localhost
端口(Port):标识正在计算机上运行的程序,不同的进程有不同的端口号。网络中的计算机是通过 IP 地址来代表其身份的,它只能表示某台特定的计算机,但是一台计算机上可以同时提供很多个服务,如数据库服务、FTP 服务、Web 服务等,我们就通过端口号来区别相同计算机所提供的这些不同的服务。端口号被规定为一个 16 位的整数 0~65535。其中,0~1023被预先定义的服务通信占用除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突
套接字(Socket):端口号与IP地址的组合得出一个网络套接字:Socket
协议(Protocal):网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。 这是一整套对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准的解决方案。只有遵守这个约定,计算机之间才能相互通信交流.为了使数据在网络上从源到达目的,网络通信的参与方必须遵循相同的规则,常用的协议如 TCP,UDP,HTTP 等
通信协议分层的思想:由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展

关于TCP/IP的认知

TCP/IP 以其两个主要协议:传输控制协议 (TCP) 和网络互联协议(IP) 而得名,实际上是一组协议,包括多个具有不同功能且互为关联的协议。IP(Internet Protocol)协议是网络层的主要协议,支持网间互连的数据通信。

TCP&UDP的各自的特点

TCP协议:
使用TCP协议前,须先建立TCP连接,形成传输数据通道
传输前,采用“三次握手”方式,是可靠的。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达。
TCP协议进行通信的两个应用进程:客户端、服务端。每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的(一对一)。
在连接中可进行大数据量的传输,并且数据的传输是基于字节流的
传输完毕,需释放已建立的连接,效率低
UDP协议:
将数据、源、目的地封装成数据包,不需要建立连接
每个数据报的大小限制在64K内
因无需连接,故是不可靠的
发送数据结束时无需释放资源,速度快

关于TCP中的三次握手&四次挥手的认知(面试题)

在这里插入图片描述

TCP编程

客户端和服务端,基于Socket套接字编程

TCP案例:客户端向服务端发送文本信息

编写TCP客户端
public class TCPClient1Test {
	public static void main(String[] args) throws IOException {
		InetAddress serverAddr = InetAddress.getLocalHost();
		//1.创建一个Socket连接对象
		Socket socket = new Socket(serverAddr, 8999);
		//2.向服务端输出字节流的对象
		OutputStream os = socket.getOutputStream();
		//3.发送信息
		PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
		writer.println("hello ! 你好! 我是Client..");
		//4.收尾
		writer.flush();
		writer.close();
		os.close();
        //4.1TCP的连接必须被释放
		socket.close();	
	}
}
编写TCP服务端
public class TCPServer1Test {

	public static void main(String[] args){
		ServerSocket server = null;
		Socket clientSocket = null;
		InputStream is = null;
		BufferedReader reader = null;
		try {
			//1.创建服务端Socket对象
			server = new ServerSocket(8999);
			
			//2.监听客户端的Socket请求
			clientSocket = server.accept();
			//3.以输入流的方式获取客户端向服务端输入的内容
			is = clientSocket.getInputStream();
			
			//3.x 做接收到流信息后,应该处理的业务
			reader = new BufferedReader(new InputStreamReader(is));
			String input = "";
			while( (input = reader.readLine()) != null ) {
				System.out.println("IP地址为:"+clientSocket.getInetAddress().getHostAddress()+"客户端发送的信息:" + input);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(is !=null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(reader !=null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			//4.释放连接
			if(clientSocket !=null) {
				try {
					clientSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(server!=null) {
				try {
					server.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}

TCP案例:客户端向服务端发送文件(上传)

编写TCP客户端
public class TCPClient2Test {

	public static void main(String[] args) throws IOException {
		InetAddress serverAddr = InetAddress.getLocalHost();
		// 1.创建一个Socket连接对象
		Socket socket = new Socket(serverAddr, 8999);
		// 2.向服务端输出字节流的对象
		OutputStream os = socket.getOutputStream();
		// 3.发送文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("G:/多线程(下).md")));
		BufferedOutputStream bos = new BufferedOutputStream(os);
		int input = -1;
		while ( (input=bis.read()) != -1) {
			bos.write(input);
		}
		
		// 4.收尾
		bos.flush();
		//给一个本次流结束的标识
		socket.shutdownOutput();
		
		bos.close();
		bis.close();
		// 4.1TCP的连接必须被释放
		socket.close();
	}
}
编写TCP服务端
public class TCPServer2Test {

	public static void main(String[] args){
		ServerSocket server = null;
		Socket clientSocket = null;
		InputStream is = null;
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;
		try {
			//1.创建服务端Socket对象
			server = new ServerSocket(8999);
			
			//2.监听客户端的Socket请求
			clientSocket = server.accept();
			//3.以输入流的方式获取客户端向服务端输入的内容
			is = clientSocket.getInputStream();
			
			//3.x 做接收到流信息后,应该处理的业务
			bos = new BufferedOutputStream(new FileOutputStream(new File("upload.md")));
			bis = new BufferedInputStream(is);
			int input = -1;
			while( (input = bis.read()) != -1 ) {
				bos.write(input);
			}
			System.out.println("接收IP地址为:"+clientSocket.getInetAddress().getHostAddress()+"文件完毕!");
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(bos !=null) {
				try {
					bos.flush();
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(is !=null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bis !=null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			//4.释放连接
			if(clientSocket !=null) {
				try {
					clientSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(server!=null) {
				try {
					server.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}

UDP编程

编写发包程序案例

public class UDPSenderTest {

	public static void main(String[] args) throws IOException {
		DatagramSocket sendSocket = new DatagramSocket();
		
		byte[] buf = "你好UDP的接收方,我是发送方".getBytes();
		InetAddress localAddress = InetAddress.getLocalHost();
		DatagramPacket sendP = new DatagramPacket(buf, 0, buf.length, localAddress, 9090);
		
		sendSocket.send(sendP);
		
		sendSocket.close();
	}

}

编写接包程序案例

public class UDPGetterTest {

	public static void main(String[] args) throws Exception{
		DatagramSocket sendSocket = new DatagramSocket(9090);
		
		byte[] buf = new byte[1024];
		DatagramPacket sendP = new DatagramPacket(buf, 0, buf.length);
		sendSocket.receive(sendP);
		
		System.out.println("接收的UDP包的内容为:"+new String(sendP.getData(), 0, sendP.getLength()));
		
		sendSocket.close();
	}

}

URL编程

public class URLTest {

	public static void main(String[] args) throws Exception{
		URL url = new URL("http://www.kfzimg.com/G05/M00/6A/AF/p4YBAFf3CNmAEei9AAIMbhFsIJk732_b.jpg");
		
		URLConnection connection = url.openConnection();
		connection.connect();
		
		InputStream is = connection.getInputStream();
		
		
		BufferedInputStream bis = new BufferedInputStream(is);
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("download_thinking_in_java.jpg")));
		
		int input = -1;
		while ( (input=bis.read())!=-1) {
			bos.write(input);
		}
		
		bos.flush();
		bos.close();
		is.close();
		bis.close();
	}
}
InputStream bis = new BufferedInputStream(is);
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("download_thinking_in_java.jpg")));
		
		int input = -1;
		while ( (input=bis.read())!=-1) {
			bos.write(input);
		}
		
		bos.flush();
		bos.close();
		is.close();
		bis.close();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值