网络通信基本要素
IP地址:InetAddress
网络中设备的标识。
不易记忆,可用主机名
本地回环地址:127.0.0.1 主机名:localhost
端口号:
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024系统使用或保留端口。
传输协议:
通讯的规则
常见协议:TCP,UDP
UDP与TCP的区别:
UDP:类似投递包裹
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k内
因无连接,是不可靠协议
不需要建立连接,速度快
TCP:类似打电话
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
两者传输的特点:
TCP传输的特点,利用各自方法得到输入或输出流,然后类似IO。
UDP传输的特点,利用send和receive方法送和接收数据包。
IP
参考InetAddress类(net包)
常用方法
因为无构造函数
静态方法:
static InetAddress getLocalHost() 返回本地主机。
static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
等等,利用静态方法获取对象
static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
等等,利用静态方法获取对象
非静态方法
getHostAddress()
返回 IP 地址字符串(以文本表现形式)。
getHostName() 获取此 IP 地址的主机名。
getHostName() 获取此 IP 地址的主机名。
例子:
import java.net.*;
class IpDemo
{
public static void main(String[] args) throws Exception
{
InetAddress i=InetAddress.getLocalHost();
System.out.println(i.toString()); //CP9-PC/192.168.0.100
System.out.println(i.getHostAddress());//192.168.0.100
System.out.println(i.getHostName());//CP9-PC
}
}
UDP传输
udp发送端
思路:1,建立updsocket服务。
2,提供数据,并将数据封装到数据包中。
3,通过socket服务的发送功能,将数据包发出去。
4,关闭资源。
//UDP发送端
import java.net.*;
class UdpSend
{
public static void main(String[] args) throws Exception
{
//1,创建Udp服务,利用DatagramSocket对象
DatagramSocket ds=new DatagramSocket();
//2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)
byte[] buf="udp发送了".getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),20000);
//3,通过socket服务,将已有的数据包发送出去。通过send方法。
ds.send(dp);
//4,关闭资源。
ds.close();
}
}
udp接收端
思路:
1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。
方便于明确哪些数据过来该应用程序可以处理。
2,定义一个数据包,因为要存储接收到的字节数据。
因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。
5,关闭资源。
//UDP接收端
class UdpRec
{
public static void main(String[] args) throws Exception
{
//1,创建udp socket,建立端点。
DatagramSocket ds=new DatagramSocket(20000);
//2,定义数据包,用于存储数据
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
//3,通过服务的receive方法将收到数据存入数据包中。
ds.receive(dp);//阻塞式方法
//4,通过数据包的方法获取其中的数据。
// InetAddress getAddress() 返回某台机器的 IP 地址
String ip=dp.getAddress().getHostAddress();
String data=new String(dp.getData(),0,dp.getLength());
//getPort() 返回某台远程主机的端口号
int port=dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
//5,关闭资源
ds.close();
}
}
练习:在发送端键盘输入,在接收端显示
import java.io.*;
import java.net.*;
class UdpSend2
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds=new DatagramSocket();
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while(null!=(line=bufr.readLine()))
{
if("886".equals(line))
break;
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),10001);
ds.send(dp);
}
ds.close();
}
}
class UdpRec2
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds=new DatagramSocket(10001);
while (true)
{
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip=dp.getAddress().getHostAddress();
String data=new String(dp.getData(),0,dp.getLength());
System.out.println(ip+".........."+data);
}
}
}
TCP传输
1,tcp分客户端和服务端。
2,客户端对应的对象是Socket。
服务端对应的对象是ServerSocket。
TCP客户端
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的。所以在建立socket服务时,
就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
因为tcp是面向连接的。所以在建立socket服务时,
就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
例:
import java.io.*;
import java.net.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端的socket服务。指定目的主机和端口
Socket s=new Socket("192.168.0.100",10002);
//为了发送数据,应该获取socket流中的输出流。
OutputStream out=s.getOutputStream();
out.write("TCP客户端发送中".getBytes());
s.close();
}
}
TCP服务端
1,建立服务端的socket服务。ServerSocket();
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。
并打印在控制台。
4,关闭服务端。(可选)
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。
并打印在控制台。
4,关闭服务端。(可选)
例:
class TcpServer
{
public static void main(String[] arg)throws Exception
{
//建立服务端socket服务。并监听一个端口。
ServerSocket ss = new ServerSocket(10002);
//通过accept方法获取连接过来的客户端对象。
//一般服务端要一直开启
while (true)
{
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
//获取客户端发送过来的数据
//由于获得了客户端的Socket,即可获得客户端的读取流
//通过读取流将数据读入缓存
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();//只关闭客户端Socket连接
}
//ss.close();//服务端是否关闭看需求
}
}