------- android培训、java培训、期待与您交流! ----------
1、网络参考模型
OSI参考模型 TCP/IP参考模型
应用层
表示层 应用层
会话层
—————————————————————————————————————
传输层 传输层
—————————————————————————————————————
网络层 网际层
—————————————————————————————————————
数据链路层
物理层 主机值网络层
2、网络通讯要素
①IP地址InetAddress
IP地址是设备在网络中的标示,IP地址的长度为32位(共有2^32个IP地址),分为4段,每段8位,用十进制数字表示,每段数字范围为0~255,段与段之间用句点隔开。一般不容易记忆,可使用主机名。例如本地回环地址:127.0.0.1其主机名为:localhost。
②端口号Port
用于标识进程的逻辑地址,不同进程的标识,有效端口:0~65535,其中0~1024系统使用或保留端口。
③传输协议
即网络间的通讯规则,常用的有TCP/IP协议、UDP
TCP:
即传输控制协议,在通讯时通过三次握手完成建立连接,形成传输数据的通道,在连接中会进行大量的数据传输,效率会稍低。当传输出现错误时能自动予以纠正。类似于打电话,需接通后才能对话。
UDP:
即用户数据包协议,在数据进行传输时不需要建立连接,是一种不可靠的协议,其将数据及原和目的地封装成大小限制在64K的数据包中,进行传输,当传输出现错误时会将丢弃。类似于对讲机,按下对讲机不管是否有人接通都可以进行说话。
3、Socket套接字
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。网络的通信其实就是数据在Socket间通过IO进行的通信
4、UDP用户数据包协议
使用UDP进行通讯,发送端的实现:
在发送端,要在数据包对象中明确目的地 IP及端口
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class SendMessage {
public static void main(String[] args) {
try {
//建立发送端口,指定端口为10000
DatagramSocket ds=new DatagramSocket();
//建立数据,并封装成数据包DatagramPacket(数据,数据长度,目的地址,端口)
byte[] buf="hahahah".getBytes();
DatagramPacket dp=new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.1.101"), 10000);
//发送数据报
ds.send(dp);
//关闭资源
ds.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} 接受端的实现:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiveMessage {
public static void main(String[] args) {
//建立udp socket
try {
DatagramSocket ds=new DatagramSocket(10000);
//定义一个用于接收数据的数据包
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
//接收数据
ds.receive(dp);
//通过数据包的方法获取其中的数据。
String data=new String(dp.getData(),0,dp.getLength());
//获取ip地址
String ip=dp.getAddress().getHostAddress();
System.out.println(ip+":"+data);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、TCP协议
通过Socket可以建立客户端,在该对象建立时,就可以去连接指定主机。因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
客户端的实现:
1、创建Socket服务。并指定要连接的主机和端口。
2、创建客户端的socket服务。指定目的主机和端口
3、为了发送数据,应该获取socket流中的输出流。
public class SendMessage {
public static void main(String[] args) {
try {
//创建Socket服务,指定要连接的主机和端口
Socket s=new Socket(InetAddress.getByName("192.168.1.101"),10000);
//从键盘获取数据
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//将数据通过socket通过输出流写出
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
String line;
while((line=br.readLine())!=null){
if("over".equals(line))
break;
//pw.println(line);
bw.write(line);
bw.newLine();//readLine将换行符最为结束标记,并不将换行符写入,需手动添加
bw.flush();//刷新
}
//关闭资源
s.close();
//pw.close();
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端的实现:
1,建立服务端的socket服务。ServerSocket();
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。
4,关闭服务端。(可选)
class ReceiveMge{
public static void main(String[] args){
try {
//建立服务端,并监听端口10000
ServerSocket ss=new ServerSocket(10000);
//获取连接过来的套接字
Socket s=ss.accept();
//
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
PrintWriter pw=new PrintWriter(System.out,true);
String line;
while((line=br.readLine())!=null){
bw.write(line.toUpperCase());
bw.newLine();
bw.flush();
pw.println(line.toUpperCase());
}
br.close();
bw.close();
//pw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结:
1、reader是阻塞式方法,readLine()需要读取到换行符,才会返回,当客户端将输入通过write方法写给服务器时,如果使用缓冲流,必须刷新,并且加上换行符,因为,当从键盘录入时,输入的换行符,在使用readLine()读入到内存中时,就被客户端的readLine()作为结束符使用了,读入到内存中的字符串是没有换行符的,在服务端读取后,将字符串处理后,发送回客户端是,也需要加上换行符并刷新。
2、PrintWrite(File/String/writer/out, boolean)自带刷新功能,PrintWriter.println();自动结束本行。
3、在一般使用中,自定义结束标记较麻烦,一般在写完数据时使用s.shutdownOutput(),告诉服务端数据写完了。
6、URL对路劲实现封装
通过将路径封装到URL中,URL内部实际对Socket进行了封装,是从应用层实现对资源的访问,通过ISO模型可知,能够将获取的资源的HTTP请求头去掉。Socket是发生在链路层,URL.openConnection()是发生在应用层。
常用的方法:
① getFile()获取URL的文件名
②getPath()获取此URL的路径
getPath()和getFile()的区别:当url后面带有访问参数时,getFile()会包括访问参数。
③getHost()获取URL的主机名
④getPort()获取URL端口号,getPort(),当没指定端口是返回值为-1。使用默认端口80。
⑤getQuery()获取URL的查询部分
getQuery()当url后面跟有访问参数时,能够获取访问参数,没有为null。
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class demo {
public static void main(String[] args){
try {
URL url=new URL("http://192.168.1.101:8080/mail/1.html?a=1&b=2");
String path=url.getPath();
String file=url.getFile();
int port=url.getPort();
String query=url.getQuery();
String host=url.getHost();
//获取连接
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
InputStream in=conn.getInputStream();//获取流对象
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
System.out.println("path:"+path+",\r\n"+"file:"+file+",\r\n"+"port:"+port+",\r\n"+"query:"+query+",\r\n"+"host:"+host);
} catch (Exception e) {
e.printStackTrace();
}
}
}
本文详细介绍了网络通信的基础知识,包括OSI参考模型、网络通讯要素、Socket套接字、UDP与TCP协议的区别与应用,以及如何使用Java进行网络编程。重点阐述了Socket的建立、数据的发送与接收过程,提供了实际的代码示例。
1万+

被折叠的 条评论
为什么被折叠?



