ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

十六、网络编程

2021-11-27 18:06:22  阅读:159  来源: 互联网

标签:String 编程 十六 网络 bw new 客户端 public socket


1.计算机网络

1.1概述

什么是网络:由(计算机)和线(网线)构造的网状结构
什么是计算机网络:不同区域的计算机,通过线路连接能够实现数据传递资源共享的方式
什么是网络编程:实现数据传递与资源共享的具体技术

1.2网络模型

概述:在实现通讯过程中软硬件结合的操作

1.3网络编程三要素

IP地址
计算机的唯一标识
有两种IP地址表示:
IPV4:分4个段,每个段最高为255;例如:192.168.1.6
IPV6:分8个段,每个段最高位FFFF;(十六进制)

IPV4分类:
A类:从1开始~126段
B类:127开始~191段
C类:192开始~223段(10个以内)
D类:224开始~239段

回环地址:127.0.0.1,代表本机测试地址


Port:
通讯软件的唯一识别:(0~65535)
0~1024: 系统已经分配或保留的端口,一般不去使用
1024以后可以使用
避开一些常用端口:例如3306,8080,1521等

协议:
TCP,UDP协议
TCP:面向连接的协议,安全但效率低--例如:打电话
UDP:无连接的协议,不安全但效率高--例如:发短信

2.网络编程

2.1INetAddress类

INetAddress类: 代表IP地址对象
可以调用相关方法得到IP地址

public class Test1 {
	public static void main(String[] args) throws UnknownHostException {
		//通过ip或主机名或域名得到ip对象
		InetAddress net1 = InetAddress.getByName("192.168.1.8");
		System.out.println(net1);
		
		//一个域名可能绑定多台服务器(多个IP)
		InetAddress[] nets = InetAddress.getAllByName("www.baidu.com");
		System.out.println(Arrays.toString(nets));
		
		InetAddress net2 = InetAddress.getLocalHost();
		System.out.println(net2);  //获取本机IP
		
	}
}

2.2TCP-客户端发数据到服务器

TCP编程:也叫做Socket编程,基于tcp协议字节流的传输协议
通讯模型: 客户端-服务器模型
服务器:
1.实例化服务器Socket对象,指定自身端口
2.监听客户端的连接,如果有客户端连接了,那么创建一个socket与客户端通讯

客户端:
1.实例化socket对象,传入服务器的ip和端口

谁先启动?  服务器先启动,有监听阻塞方法

//案例:服务器与客户端建立TCP连接后,进行通讯;
//客户端给服务器发数据,服务器也可以给客户端发数据

public class Server {
	public static void main(String[] args) throws IOException {
		//实例化服务器socket,指定自身端口
		ServerSocket serverSocket = new ServerSocket(9527);
		//调用accept监听客户端连接,如果有客户端连接了,则创建了socket对象与客户端通讯
		Socket socket = serverSocket.accept();  //阻塞方法
		System.out.println("有一个客户端连上来了");
		
		//接收数据--读
		InputStream is = socket.getInputStream();
		byte[] b = new byte[1024];
		int len = is.read(b);
		System.out.println(new String(b, 0,len));
		
		
		//服务器发送数据--写
		OutputStream os = socket.getOutputStream();
		os.write("服务器回应给客户端的数据".getBytes());
	
		IOUtils.closeAll(is,os,socket,serverSocket);
	}
}


-----Client-------
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 9527);
		
		//通过字节流发数据--写
		OutputStream os = socket.getOutputStream();
		os.write("客户端发送的数据..".getBytes());
		
		//客户端的接收--读
		InputStream is = socket.getInputStream();
		byte[] b = new byte[1024];
		int len = is.read(b);
		System.out.println(new String(b, 0,len));
		
		//统一资源关闭: 先关小的,再关大的
		IOUtils.closeAll(os,is,socket);
	}
}

2.3客户端上传图片到服务器

//案例:使用tcp编程实现图片上传到服务器
//分析:先在客户端通过输入字节流读取图片资源,然后写到socket中
     //在服务器的socket中通过读字节流接收,然后再写到服务器本地
-------Server--------
public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(10086);
		Socket socket = ss.accept();
		
		//从socket中读取字节流
		InputStream is = socket.getInputStream();
		FileOutputStream fos = new FileOutputStream("d:\\a.jpg");
		byte[] b = new byte[1024];
		int len;
		while((len=is.read(b))!=-1) {
			fos.write(b, 0, len);
		}
		System.out.println("服务器接收成功~!");
		IOUtils.closeAll(fos,is,socket,ss);
	}
}


-------Client--------
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 10086);
		
		//客户端从图片中读取资源
		FileInputStream fis = new FileInputStream("b.jpg");
		byte[] b = new byte[1024];
		int len;
		OutputStream os = socket.getOutputStream();
		while((len=fis.read(b))!=-1) {
			os.write(b, 0, len);
		}
		System.out.println("上传到服务器~~");
		IOUtils.closeAll(os,fis,socket);
		
	}
}

2.4多个客户端发数据给服务器

//案例:多个客户端与服务器聊天
//服务器:
//1.来一个客户端,那么产生一个socket与客户端通讯---多线程
//2.从socket总接收文本内容,通过字符缓冲流封装

//客户端:
//1.循环从客户端录入数据

------服务器------
public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(10010);
		//死循环实时监听客户端连接
		while(true) {
			Socket socket = ss.accept();
			System.out.println("有一个客户端进行了连接...");
			new ServerThread(socket).start();//在开辟的路径中,执行socket操作
		}
	}
}


------服务器线程------
public class ServerThread extends Thread {
	private Socket socket;
	
	public ServerThread(Socket socket) {
		this.socket = socket;
	}
	
	@Override
	public void run() {
		InputStream is = null;
		BufferedReader br = null;
		try {
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			while(true) {
				String msg = br.readLine();
				System.out.println(msg);
				
				if(msg.equals("886")) {
					break;
				}
			}
		} catch (IOException e) {
			System.out.println("有异常中断。。。");
		}finally {
			System.out.println("有一个客户端退出了连接");
			IOUtils.closeAll(is,br,socket);
		}
		
	}
}


------客户端------
public class Clent {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 10010);
		
		System.out.println("请从客户端进行录入:");
		OutputStream os = socket.getOutputStream();  //字符缓冲流包装
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		//从键盘录入
		Scanner sc = new Scanner(System.in);
	
			while(true) {
				String msg = sc.next();
				bw.write(msg);
				bw.newLine();  //换行
				bw.flush();    //刷新
				
				if(msg.equals("886")) {  //约定
					break;
				}
			}
			IOUtils.closeAll(os,bw,socket);
	}
}

3.网络编程案例

3.1注册功能

//案例:注册功能
//分析:
//1.客户端与服务器建立连接
//2.客户端准备好注册数据,拼成一个字符串;例如:{id:"1001",name:"zs",age:30}
//3.发送注册数据,服务器接收数据
//4.服务器拆分数据,取出id对应的value作为key,接收的注册信息作为value
//5.判断key在配置文件中是否存在,如果存在,则返回"已存在"
//6.不存在,把这些数据存到配置文件,并返回“注册成功”
-----服务器------
public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(9527);
		Socket socket = ss.accept();
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine(); //{id:1001,name:zs,age:30}
		String strId = msg.split(",")[0];  //{id:1001
		String id = strId.split(":")[1];   //1001
		
		//通过Properties集合去加载配置文件
		Properties p = new Properties();
		p.load(new FileInputStream("user.properties"));
		
		OutputStream os = socket.getOutputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		if(p.containsKey(id)) {
			bw.write("已存在");
			
		}else {
			Tool.saveProperties(id,msg);  //将数据存储到配置文件
			bw.write("注册成功");
		}
		bw.newLine();
		bw.flush();
		
		IOUtils.closeAll(bw,os,br,is,socket);
		
	}
}


-----客户端------
public class Client {
	public static void main(String[] args) throws IOException {
		Socket socket = new Socket("127.0.0.1",9527);
		OutputStream os = socket.getOutputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		
		String json = getData(); //{id:1001,name:zs,age:30}
		//发数据
		bw.write(json);
		bw.newLine();
		bw.flush();
		
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine();
		System.out.println("服务器响应:"+msg);
		
		IOUtils.closeAll(is,br,os,bw,socket);
	}

	private static String getData() {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入ID:");
		String id = sc.next();
		System.out.println("请输入用户名:");
		String name = sc.next();
		System.out.println("请输入年龄:");
		int age = sc.nextInt();
		return "{id:"+id+",name:"+name+",age:"+age+"}";
	}
}

----user.properties在src目录下建一个----

----工具类----
public class Tool {
	public static void saveProperties(String id, String msg) throws FileNotFoundException, IOException {
		Properties properties = new Properties();
		properties.put(id, msg);
		properties.store(new FileOutputStream("user.properties"), "");
	}
}

----------CloseAll------
public class CloseAll {
	public static void closeAll(Closeable... closeable) throws IOException {
		if(closeable!=null) {
			for (Closeable c: closeable) {
				c.close();
			}
		}
	}
}

3.2登录功能

/**
 * 1. 用户登录:
	客户端:
	输入ID,name;并拼接成字符串,例如“{id:1001,name:zs}”
	将该字符串传到服务器;
	服务器:
	在服务器中根据拆分的id值去匹配配置文件user.properties中是否存在key为1001的值
	如果有则取出value,拆分出name的值;和传过来的json数据里面的id和name比较
	匹配成功则返回“登录成功”到客户端;如果不匹配,则返回“登录失败”到客户端  
 *  */
-----------Client---------------
public class Client {

	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1",9090);
		OutputStream os = socket.getOutputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		
		String json = getData();  //{id:1001,name:zs,age:30}
		
		//发数据
		bw.write(json);
		bw.newLine();
		bw.flush();
		
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine();
		System.out.println("服务器响应:"+msg);
		OutputStream osa=socket.getOutputStream();
		BufferedWriter bwa = new BufferedWriter(new OutputStreamWriter(osa));
		
		System.out.println("=====登录界面======");
		//登录
	
		
		String jsons = getlogin();
			
		//发登录的数据给服务器
		bwa.write(jsons);
		bwa.newLine();
		bwa.flush();
		
		
		System.out.println(br.readLine());
		
		CloseAll.closeAll(is,br,bw,os,osa,bwa,socket);
	}
	private static String getlogin() {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入用户名(ID):");
		String id = scanner.next();
		System.out.println("请输入姓名(name):");
		String name = scanner.next();
		return "id:"+id+",name:"+name+"";
	}
	private static String getData() {
		Scanner sc=new Scanner(System.in);
		System.out.println("请输入ID:");
		String id=sc.next();
		System.out.println("请输入用户名:");
		String name=sc.next();
		System.out.println("请输入年龄:");
		int age=sc.nextInt();
		return "id:"+id+",name:"+name+",age:"+age;
		
	}

}

---------------Server------------------
public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(9090);
		Socket socket = ss.accept();
		
		//接受客户端的数据,并且剪切数据
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine();
		String strId = msg.split(",")[0];
		String id = msg.split(":")[1];
		
		//对文件进行加载(读取内部文件)
		Properties pro = new Properties();
		pro.load(new FileInputStream("users.properities"));
		
		OutputStream os = socket.getOutputStream();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
		if(pro.containsKey(id)) {
			System.out.println("已经存在");
		}else {
			Tools.saveProperities(msg);
			bw.write("注册成功");
		}
		bw.newLine();
		bw.flush();
		
		//接受客户端的数据,并且剪切
		InputStream isa = socket.getInputStream();
		BufferedReader bra = new BufferedReader(new InputStreamReader(isa));
		String msgs = bra.readLine();
		
		//先剪切用户名
		String strIds = msgs.split(",")[0];
		String ids = strIds.split(":")[1];
		
		//剪切密码
		String strName = msgs.split(",")[1];
		String name=strName.split(":")[1];
		
		//读取内部文件
		Properties p = new Properties();
		p.load(new FileInputStream("users.properities"));
		
		//将获取客户端的数据,对文件剪切的内容进行比对
		OutputStream osa = socket.getOutputStream();
		BufferedWriter bwa = new BufferedWriter(new OutputStreamWriter(osa));
		
		if(p.containsKey("id")&&p.containsKey("name")) {
			bw.write("登陆成功!");
		}else {
			bw.write("您输入的用户名或姓名有误!");
		}
		
		CloseAll.closeAll(bw,os,br,is,isa,bra,osa,bwa,socket);
	}

}

----------------工具类-------------------
public class Tools {
	public static void saveProperities(String msg) throws FileNotFoundException, IOException {
		Properties pro = new Properties();
		String[] str = msg.split(",");
		
		for(int i =0;i<str.length;i++) {
			String[] str1 = str[i].split(":");
			pro.put(str1[0], str1[1]);
		}
			
		pro.store(new FileOutputStream("users.properities"),"");	
	}
}

-------------------CloseAll-------------------
public class CloseAll {
	public static void closeAll(Closeable... closeable) throws IOException {
		if(closeable!=null) {
			for (Closeable c: closeable) {
				c.close();
			}
		}
	}
}

3.3聊天室程序

//案例:聊天室程序
//分析: 多人聊天---多线程
//1.通过多线程形式接收多个客户端的连接
//2.客户端要录入姓名,传入服务器接收,并存储到线程中
//(注意:客户端的发送和接收要分为两个线程,才能方便群发)
//3.服务器给客户端回应“欢迎进入聊天室”
//4.该客户端就可以实时发数据聊天了
//5.要实现服务器群发信息给客户端,需要先将所有线程对象存储
//6.退出方式,客户端退出,其他用户应该都知道

-------服务器-------
public class Server {
	public static List<ServerThread> list = new ArrayList<ServerThread>();
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(9527);
		//多线程方式监听及创建socket
		while(true) {
			Socket socket = ss.accept();
			System.out.println("有一个客户端进来了");
			ServerThread st = new ServerThread(socket);
			st.start();
			list.add(st);  //存储线程对象
		}
	}
}


------服务器线程-------
public class ServerThread extends Thread {
	private Socket socket;
	
	private BufferedReader br;
	private BufferedWriter bw;
	
	public ServerThread(Socket socket) throws IOException {
		this.socket = socket;
		br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
	}
	
	@Override
	public void run() {
	
		try {
			sendHello();  //欢迎
			
			while(true){
				String name = this.br.readLine(); //读取到数据后,发给自身
				String msg = this.getName()+"说:"+name;
				//循环遍历线程对象,除了自己,都发一份出去
				for(ServerThread st : Server.list) {
					if(st!=this) {
						st.bw.write(msg);
						st.bw.newLine();
						st.bw.flush();
					}
				}
			}
		} catch (Exception e) {
			String msg = this.getName()+"退出了聊天室";  //群发退出信息
			Server.list.remove(this);  //将当前线程对象在集合中移除
			
			for(ServerThread st : Server.list) { //移除后群发
				try {
					st.bw.write(msg);
					st.bw.newLine();
					st.bw.flush();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			
		}finally {
			IOUtils.closeAll(bw,br,socket);
		}
	}

	private void sendHello() throws IOException {
		String name = br.readLine(); //读取到数据后,发给自身
		String msg = "【温馨提示】:欢迎"+name+"进入聊天室";
		this.setName(name);  //记录客户的访问
		bw.write(msg);
		bw.newLine();
		bw.flush();
	}
}


------客户端-------
public class Client {
	public static void main(String[] args) throws IOException {
		Socket socket = new Socket("127.0.0.1",9527);
		
		//客户端读写分离
		new WriteClient(socket).start();
		
		new ReadClient(socket).start();

	}
}



-------客户端写线程-------
public class WriteClient extends Thread {
	private Socket socket;
	
	public WriteClient(Socket socket) {
		this.socket = socket;
	}
	
	@Override
	public void run() {
		OutputStream os = null;
		BufferedWriter bw = null;
		try {
			os = socket.getOutputStream();
			bw = new BufferedWriter(new OutputStreamWriter(os));
			System.out.println("请输入用户名:");
			Scanner sc = new Scanner(System.in);
			
			while(true) {
				String name = sc.next(); //第一次是输入名字,后面就是聊天内容
				bw.write(name);
				bw.newLine();
				bw.flush();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			IOUtils.closeAll(os,bw,socket);
		}
		
	}
}



-------客户端读线程--------
public class ReadClient extends Thread {
	private Socket socket;
	
	public ReadClient(Socket socket) {
		this.socket = socket;
	}
	
	@Override
	public void run() {
		InputStream is = null;
		BufferedReader br = null;
		try {
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			while(true) {
				String msg = br.readLine();
				System.out.println(msg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			IOUtils.closeAll(is,br,socket);
		}
		
	}
}

标签:String,编程,十六,网络,bw,new,客户端,public,socket
来源: https://blog.csdn.net/Yeung_ZY/article/details/121580374

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有