Java之网络编程基础

推荐资源站:https://zhimalier.com/

前天对java网络基础进行了以下总结,相信会有很多不足之处!请大牛多多指导,以寻求更好的进步!  在此之前,先说一说基础知识,个人对概念性的知识不是太感冒,但是不了解的话会很坑的。所以喽,还是总结看看!

一、网络的基本概念

1、计算机网络,说白了就是把分布在不同地区的计算机通过线等设备链接起来,形成一个大规模的网络系统,从而达到信息的传递。

2、网络体系:国际化标准组织ISO在1978年提出了OSI(Open System Interconnection)模型,中文名是开放系统互联参考模式,它把网络分为了7层物理层、数据链路层、网络层、传输层、会话层、表示层、应用层


网络编程额三要素:IP地址、端口号、通信协议
      IP地址(IP Address)
      每台主机都必须有一个唯一的,因特网的IP地址具有全球唯一性!
      IP地址IP地址 = 网络ID +主机ID
      网络ID:标识计算机或网络设备所在的网段
      主机ID:标识特定主机或网络设备
      格式:int型、 32位、由4个8位二进制数组成
端口号
      Ip地址其实就是方便找到你想联系的电脑,而端口号则标明的是该计算机的程序应用。他是抽象的软件结构。端口号可以从0到65535,通常分为3类:
*、公认端口(Well Known Ports):从0到1023,它们紧密绑定(Binding)一些服务。
*、注册端口(Registered Ports):从1024到49151。它们松散地绑定一些服务。
*、动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。


两类传输通信协议

1、TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个 socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。

2、UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP/IP虽然名字是TCP,但是他的传输层包含TCP和UDP两个协议
    比较:  UDP相当于发短信(有字数限制)
    不需要建立链接
    数据报的大小限制在64K内
    效率高,不安全,容易丢包
    TCP相当于打电话,需要建立链接
    效率相对较低,数据传输安全

 

三次握手 (点名-->签到-->确认)

二、socket套接字的java网络编程
1、TCP对应的是服务器的ServerSocket和客户端的SocketJava中使用Socket完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续性的、点对点的通讯连接

在Socket的程序开发中,服务器端使用ServerSocket等待客户端的连接,对于java的网络程序来讲,每一个客户端都使用一个Socket对象表示。

socket通讯流程:
(1)创建Socket(客户端) ServerSocket(服务端) 
(2)客户端/服务端打开并连接Socket的输入/输出流
(3)按照一定的规则进行读/写操作
(4)关闭Socket相关

//实例代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * TCP socket网络编程
 * 		1、服务器serversocket建立一个服务器端,还有一个客户端,两者通过
socket对象建立通道连接起来
 * 		2、两者可以通过流进行数据传输    如果数据有类型,使用
datainputStream  dataoutputStream,  object
 * 		3、实际上数据访问还是通过流实现的,但是两端都是来自网络   
 * @author Administrator
 *
 */
public class LoginClient {
	//使用字符流发送数据,一定要及时刷新flush,每写一行数据需要 newline
	public static void main(String[] args) throws UnknownHostException, IOException {
		//1、socket套接字,用来打通通道
		Socket s = new Socket("127.0.0.1",8888);//打开了本机上的端口号为8888的程序的通道
		//输出流,用来向服务器发送数据
		OutputStream os = s.getOutputStream();
		InputStream is = s.getInputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		bw.write("发送第一行内容");
		bw.newLine();
		bw.write("发送第二行内容");
		bw.newLine();
		bw.flush();
		//2、拿到服务器给出的反馈 
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		System.out.println(br.readLine());
		//3、关闭流
		br.close();
		bw.close();
		is.close();
		os.close();
		s.close();
	}

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Tcp Socket 双向: 客户端向服务器发送数据,服务器接收到之后给出反馈 模拟登陆
 * @author Administrator
 * 
 */
public class LoginServer {
	public static void main(String[] args) throws IOException {
		// 1、创建serversocket对象,并指定地址和端口号
		ServerSocket ss = new ServerSocket(8888);
		// 2、使用serversocket拿到 socket对象,socket是一个套接字,连接应用层和传输层,打开通道
		Socket s = ss.accept();
		// 3、socket对象拿到了访问该服务器的对象的数据
		InputStream is = s.getInputStream();
		OutputStream os = s.getOutputStream();
		// 处理拿到的数据
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		String name = br.readLine();
		String pwd = br.readLine();
		System.out.println(name+"\t"+pwd+"登陆服务器");
		if (name.equals("bjsxt") && pwd.equals("bjsxt")) {
			// 当登陆成功,给用户反馈成功
			bw.write("恭喜你登陆成功!!!!");
			bw.flush();
		} else {
			bw.write("账号或密码错误!!!!");
			bw.flush();
		}
		//4、关闭流
		bw.close();
		br.close();
		os.close();
		is.close();
		s.close();
		ss.close();
	}
}

//对象流的代码实例

import java.io.Serializable;

/**
 * 封装了用户信息
 * @author Administrator
 *
 */
public class User implements Serializable{
	String name;//登录账号
	String pwd;//密码
	int id;//身份标识
	public User(String name, String pwd, int id) {
		super();
		this.name = name;
		this.pwd = pwd;
		this.id = id;
	}
	
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 基于TCP协议的 socket网络编程 1、服务器serversocket建立一个服务器端,还有一个客户

端,两者通过socket对象建立通道连接起来
 * 2、两者可以通过流进行数据传输 如果数据有类型,使用datainputStream 
dataoutputStream, object
 * 3、实际上数据访问还是通过流实现的,但是两端都是来自网络
 * @author Administrator
 * 
 */
public class LoginClient {
	// 使用字符流发送数据,一定要及时刷新flush,每写一行数据需要 newline
	public static void main(String[] args) throws UnknownHostException,
			IOException {
		Socket s = new Socket("127.0.0.1", 8888);
		ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
		oos.writeObject(new User("望舒", "111111", 1));
		// 读取服务器给的反馈
		InputStream is = s.getInputStream();
	        BufferedReader br = new BufferedReader(new InputStreamReader(is));
		System.out.println(br.readLine());
		// 关闭流
		is.close();
		oos.close();
		s.close();
	}
}

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Tcp Socket 双向: 客户端向服务器发送对象,服务器接收到之后给出反馈 模拟登陆
 * 			利用线程知识  可以多客户端
 * @author Administrator
 * 
 */
public class LoginServer {

	public static void main(String[] args) throws IOException,
			ClassNotFoundException {
		// 1、创建一个服务器,指定端口号
		ServerSocket ss = new ServerSocket(8888);
		boolean flag = true;
		while (flag) {
			Socket s = ss.accept();
			new LoginThread(s).start();
		}
		ss.close();
	}
}

class LoginThread extends Thread {
	Socket s = null;

	public LoginThread(Socket s) {
		this.s = s;
	}

	@Override
	public void run() {
		try {
			login();
		} catch (ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 接收客户端信息的方法
	public void login() throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
		User user = (User) ois.readObject(); //向下转型
		System.out.println(user.name + "正在登录");
		OutputStream os = s.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		bw.write("服务端接收成功");
		bw.flush();
		os.close();
		ois.close();
		s.close();
	}
}


2、UDP对应的是DatagramSocket。
实现流程:
服务器端(server):
1. 构造DatagramSocket实例,指定本地端口。
2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。
3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.
客户端(client):
1. 构造DatagramSocket实例。
2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。
3.结束后,调用DatagramSocket的close方法关闭。


不多说,实例代码:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

/**
 * 一对多聊天
 * 
 * @author Administrator
 * 
 */
public class UdpServer {

	public static void main(String[] args) throws Exception {
		// 服务器
		DatagramSocket ds = new DatagramSocket(6666);
		Scanner input = new Scanner(System.in);
		boolean flag = true;
		while (flag) {
			// dengdai客户端发送消息
			byte bs[] = new byte[1024];
			DatagramPacket dp = new DatagramPacket(bs, bs.length);
			ds.receive(dp);
			// 解析数据
			String str = new String(dp.getData(), 0, dp.getLength());
			// str xiaomi:string
			System.out.println(str);
			// 端口号和ip地址不确定
			int port = dp.getPort();
			InetAddress ia = dp.getAddress();
			System.out.println(ia.getHostAddress());
			String msg = input.next();
			// 把消息发送给客户端
			DatagramPacket dp1 = new DatagramPacket(msg.getBytes(),
					msg.getBytes().length, ia, port);
			ds.send(dp1);
		}
		ds.close();
	}
}

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

public class UdpClient {

	public static void main(String[] args) throws Exception {
		// 1、创建一个客户端 并指定端口
		DatagramSocket ds = new DatagramSocket(8881);
		boolean flag = true;
		while (flag) {
			// 2、准备数据
			Scanner input = new Scanner(System.in);
			String str = input.next();
			str = "客户端说:"+str;
			//结束客户端
			if(str.equals("exit") || str.equals("quit")){
				break; //打断循环    
				//continue: 打断当前这次循环执行下一次
				//return 结束方法
			}
			// 3、打包数据
			DatagramPacket dp = new DatagramPacket(str.getBytes(),
					str.getBytes().length,
					InetAddress.getByName("192.168.1.218"), 8888);
			// 4、发送数据
			ds.send(dp);
			// 5、接收服务器端的反馈
			byte[] buf = new byte[1024];
			DatagramPacket dp1 = new DatagramPacket(buf, buf.length);
			ds.receive(dp1);
			System.out.println("服务器说:" + new String(dp1.getData()));
			// 6、关闭客户端
		}
		ds.close();
	}
}
	
//实例二:发送文件
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * 通过udp传递文件
 * @author Administrator
 * 
 */
public class UdpServer {

	public static void main(String[] args) {
		DatagramSocket ds = null;
		boolean flag = true;
		try {
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream("e:\\xiaomiyanzhao.gif", true));
			ds = new DatagramSocket(6666);
			// 等待接收数据
			byte[] bs = new byte[2000];
			while (flag) {
				DatagramPacket dp = new DatagramPacket(bs, 0, bs.length);
				// 把数据读取到数据报中
				ds.receive(dp);
				// 输出流输出数据
				bos.write(dp.getData(),0,dp.getLength());
			}
			bos.close();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			ds.close();
		}
	}
}

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UdpClient {
	// 客户端,用来发送文件
	public static void main(String[] args) throws IOException {
		DatagramSocket ds = new DatagramSocket(8888);
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"d:\\5.gif"));
		byte bs[] = new byte[1024];
		int len;
		while ((len = bis.read(bs)) != -1) {
			DatagramPacket dp = new DatagramPacket(bs, len,
					InetAddress.getByName("192.168.1.218"), 6666);
			ds.send(dp);
		}
		System.out.println("发送成功-----》");
		bis.close();
		ds.close();
	}
}


说了这么多 还是自己敲代码来的实在!!  先到这不写了,敲代码去!!

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝麻粒儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值