物联网实训笔记_网络编程


文章目录

  • 物联网实训笔记_网络编程
  • 网络编程基本概念:
  • 1、计算机网络
  • 2、网络通信
  • 3、OSI(Open System Interconnection)参考模型
  • 4、OSI各层所使用的协议
  • 基于TCP的Socket编程步骤:
  • 1.服务器程序编写:
  • 2.客户端程序编写:
  • 实训代码:
  • 服务端和客户端的简易聊天代码(一):
  • 服务端和客户的数据发送对象的相关代码(二)
  • 小结


网络编程基本概念:

1、计算机网络

计算机网络是相互连接的独立自主的计算机的集合,
最简单的网络形式由两台计算机组成。

2、网络通信

IP地址:
1.IP网络中每台主机都必须有一个惟一的IP地址;本机ip 127.0.0.1(本机地址)
2.IP地址是一个逻辑地址;动态改变 电脑的唯一标示:物理地址
3.因特网上的IP地址具有全球唯一性;
4.32位,4个字节,常用点分十进制的格式表示,例如:192.168.0.16。

协议:
1.为进行网络中的数据交换(通信)而建立的规则、标准或约定;(=语义+语法+规则) http;
2.不同层具有各自不同的协议。
www.baidu.com 统称为域名—>ip:port

端口号:
端口使用一个16位的数字来表示,它的范围是0–65535,1024以下的端口号保留给预定义的服务。例如:http使用80端口。
ip:查找主机
port:查找主机上的对应服务
端口号
gmail(google邮件系统) smtp 587 pop3 995
http(超文本协议 网页访问) 80
smtp 25 pop3(邮件协议)110 smtp和pop3是邮件发送与接受协议
telnet(远程登入) 23 客户端登陆到服务器端协议
ftp(文件上传与下载) 21端口负责发起和建立双方的连接,20负责传输数据!

3、OSI(Open System Interconnection)参考模型

物理层:二进制传输,确定如何在通信信道上传递比特流;
数据链路层:加强物理层的传输功能,建立一条无差错的传输线路;
网络层:在网络中数据到达目的地有很多线路,网络层就是负责找出最佳的传输线路;
传输层:传输层为源端计算机到目的端计算机提供可靠的数据传输服务,隔离网络的上下层协议,使得上层网络应用的协议与下层无关;
话层会:在两个相互通信的应用进程之间建立、组织和协调其相互之间的通信;
表示层:处理被传送数据的表示问题,也就是信息的语法和语义,如有必要将使用一种通用的格式在多种格式中进行转换;
应用层:为用户的应用程序提供网络通信服务;

OSI(Open System Interconnection)参考模型并不是物理实体上存在这七层,这只是功能的划分,是一个抽象的参考模型。进行网络通信时,每层提供本层对应的功能;
1.通信实体的对等层之间不允许直接通信,它们之间是虚拟通信,实际通信在最底层完成;
2.各层之间是严格单向依赖;
3.上层使用下层提供的服务 — Service user;
4.下层向上层提供服务 — Service provider。
5.对等层实体之间虚拟通信;
6.下层向上层提供服务,实际通信在最底层完成。

4、OSI各层所使用的协议

1.应用层:远程登录协议Telnet、文件传输协议FTP(网上下载一个软件或者资料的时候就会使用该协议)、 超文本传输协议HTTP(使用较多,通过IE浏览一个网页的时候就使用该协议)、域名服务DNS(使用较多,通过网络访问一个计算机一般不使用该主机的IP地址,而是通过该主机的域名访问)、简单邮件传输协议SMTP(通过Foxmail发送邮件)、邮局协议POP3等(通过Foxmail收邮件);

2.传输层:传输控制协议TCP、用户数据报协议UDP;
TCP:面向连接的可靠的传输协议;在利用TCP协议进行通信的时候,首先要经过三步握手建立起通信双方的连接,一旦连接建立后就可以通信了。TCP协议提供数据确认和重传的机制,保证数据一定能够到达数据接收端。像打电话。

UDP:是无连接的,不可靠的传输协议;采用UDP协议进行通信时,不需要建立连接,可以直接向一个IP地址发送数据,至于是不是能够收到不能保证,发送过程中数据有可能丢失、IP地址可能不存在、再者IP地址代表的主机没有运行等原因都可能导致不能接收到数据。

3.网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。

基于TCP的Socket编程步骤:

1.服务器程序编写:

①调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上;
②调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字;
③调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
④最后关闭通信套接字。

2.客户端程序编写:

①调用Socket()创建一个流套接字,并连接到服务器端; Socket(ip,port)
②调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收; 
③最后关闭通信套接字。

实训代码:

服务端和客户端的简易聊天代码(一):

服务端的代码:

package tcpTest;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServertClient {
	public static void main(String[] args) throws Exception {
		ServerSocket ss=new ServerSocket(1000);
		Socket socket=ss.accept();
		
		OutputStream os=socket.getOutputStream();
		DataOutputStream dos=new DataOutputStream(os);
		
		/**
		 * 从终端输入内容
		 * 读取终端输入的内容
		 * 逐行读取
		 */
		InputStreamReader isr=new InputStreamReader(System.in);
		BufferedReader br=new BufferedReader(isr);
		
		InputStream is=socket.getInputStream();
		DataInputStream dis=new DataInputStream(is);
		
		while(true) {
			String str=br.readLine();
			System.out.println("服务器说:"+str);
			dos.writeUTF(str);
			dos.flush();
			String msg=dis.readUTF();
			System.out.println("客户端说:"+msg);
			
		}
		
	}

}

接收端的代码:

package tcpTest;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class SimpleClient {
public static void main(String[] args) throws Exception {
	Socket socket=new Socket("127.0.0.1",1000);
	
	InputStream io=socket.getInputStream();
	DataInputStream dis=new DataInputStream(io);
	
	OutputStream os=socket.getOutputStream();
	DataOutputStream dos=new DataOutputStream(os);
	
	InputStreamReader isr=new InputStreamReader(System.in);
	BufferedReader br=new BufferedReader(isr);
	
	while(true) {
		String str=dis.readUTF();
		System.out.println("服务器说:"+str);
		String msg=br.readLine();
		System.out.println("客户端说:"+msg);
		dos.writeUTF(msg);
		dos.flush();
		}
	}
}

服务端和客户的数据发送对象的相关代码(二)

封装对象代码

package WetTest;

import java.io.Serializable;

public class Student implements Serializable {
	private int id;
	private String name;
	private int age;
	
	public Student(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}
	/**
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}
	
	
	
	
}

服务端的代码

package WetTest;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
/**多线程的应用的简单介绍
 * 客户端作为
 * 大数据对硬件有要求,性能中等的电脑,16gb的内存
 * 多个客户端
 * Runable接口或者继承Thread,都需要重写run方法
 * 内部类
 */




public class ServerTest {
	
	private ServerSocket ss;
	private Socket s;
	private InputStream is;
	private ObjectInputStream ois;
	
	public static void main(String[] args) {
		ServerTest st=new ServerTest();//先拿外边的类
		Handler handler=st.new Handler();//再new里面的内部类
		handler.start();
	}
	
	
	public void shutdown() throws Exception {
		if(ois!=null)ois.close();
		if(is!=null)is.close();
		if(s!=null)s.close();
		if(ss!=null)ss.close();
	}
	
	
//内部类
	private class Handler extends Thread{
		//重写run()
		public void run() {
			System.out.println("服务器已经开启,等待连接");
			try {
				ss=new ServerSocket(10001);
				s=ss.accept();
				System.out.println("已完成连接");
				is=s.getInputStream();
				ois=new ObjectInputStream(is);
				System.out.println("数据开始接受...");
				List<Student> list=(List<Student>) ois.readObject();
				System.out.println("数据接收完毕,开始打印输出...");
				for(Student s:list) 
				{System.out.println(s);}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			try {
				shutdown();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
			
			
		}
		
	}
		
}

客户端的代码

package WetTest;
//发送数据

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.sound.sampled.LineListener;

public class ClientTest {
	public static void main(String[] args) throws Exception {
		Socket socket=new Socket("127.0.0.1",10001);
		//从文件中读取,封装,发送出去
		
		//读取 因为是一行行的,所以希望逐行读取
		FileReader fr=new FileReader("C:\\Users\\daier\\eclipse-workspace\\TCPtest\\src\\WetTest\\test.txt");
		BufferedReader br=new BufferedReader(fr);
		
		String str=null;
		String [] s=null;
		Student student=null;
		ArrayList<Student> list=new ArrayList<Student>();
		
		while((str=br.readLine())!=null) {
			s=str.split("[:]");//冒号是java的关键字,所以[]起来
			student =new Student(Integer.parseInt(s[0]),s[1],Integer.parseInt(s[2]));
			System.out.println(student);
			list.add(student);
		}
		System.out.println("建立客户和服务端的连接");
		//发送数据
		OutputStream os=socket.getOutputStream();
		ObjectOutputStream oos=new ObjectOutputStream(os);//记得将发送的对象序列化 继承Seria什么的接口
		oos.writeObject(list);
		oos.flush();
		System.out.println("客户端完成发送任务");
		
		
	}
}

小结

网络编程需要注意端口号,有的时候端口号会发生占用的的问题,这时候需要换端口,可以在cmd窗口中使用密令
netstat -ano,列出所有端口使用情况
netstat -aon|findstr 端口号,查找该 端口详情和对应的进程的 PID值
tasklist|findstr “PID值”,查看该进程详情
之后可以在任务管理器中关闭相应PID的进程

发送的数据要注意发送的编码格式,有的时候因为编码格式的问题会出现字符不相等的情况.

java没有直接提供删除文档里面内容的方法,我的解决方法是,把要读取的文件遍历,再写入新的文件之中.在写入新的文件之中做文章,完成删除,修改.