物联网实训笔记_网络编程
文章目录
- 物联网实训笔记_网络编程
- 网络编程基本概念:
- 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没有直接提供删除文档里面内容的方法,我的解决方法是,把要读取的文件遍历,再写入新的文件之中.在写入新的文件之中做文章,完成删除,修改.