特殊IP地址段
127.0.0.1
127.X.X.X是本地的loopback地址,域名为localhost,在windows和linux上等价于localhost,我们习惯上使用127.0.0.1。
在命令行上ping 127.0.0.1——127.255.255.254之间的任意地址,结果都是一样的。正常的网络包从IP层进入链路层,然后发送到网络上,而发向loopback地址的包,直接在IP层短路了,也就是说发到IP层的包直接在IP层被接收了。
0.0.0.0
IPV4中,0.0.0.0地址被用于表示一个无效的,未知的或者不可用的目标。
所以ping 0.0.0.0是无效的,故0.0.0.0只能用作源地址。
用途:
当一台主机还没有被分配IP地址的时候,用于表示主机本身。
在服务器中,0.0.0.0指的是本机上的所有IPV4地址,如果一个主机有两个IP地址,192.168.1.1 和 10.1.2.1,并且该主机上的一个服务监听的地址是0.0.0.0,那么通过两个ip地址都能够访问该服务。
套接字(端口号+IP)
网络通信使用IP地址标识互联网上的计算机,使用端口号标识服务器上的进程(程序)。当两个程序需要通信是,他们可以通过使用Socket类建立套接字对象并连接在一起。
端口号规定为一个16位的0~65535之间的整数,其中,0 ~ 1023被预先定义的服务通信占用(如 telnet占用端口23,http占用端口80),除非需要访问这些特定服务,否则就应该使用1024 ~ 65535这些端口中的某一个进行通信,以免发生端口冲突。
TCP通信
服务器端:
ServerSocket的构造方法是ServerSocket(int port),port是一个端口号。port必须和客户呼叫的端口号相同。
当服务器的ServerSocket对象建立之后,就可以使用accept()方法将客户端的套接字与服务器端的套接字连接起来。accept()方法会返回一个和客户端Socket对象相连接的Socket对象,另外accept()方法也会阻塞线程的执行,直到接收到客户的呼叫。
实际数据都是通过socket进行传入传出的,ServerSocket 只是用于获得一个服务器套接字。
客户端:
①手动创建客户端:
try { Socket clientsocket=new Socket("http://192.168.0.78",9999);
}catch(IOException e){}
客户端程序使用Socket类建立负责连接到服务器的套接字对象。
Socket构造方法:Socket(String host, int port),参数host是服务器的IP地址,port是一个端口号。
②在命令行输入telnet指令,使用telnet客户端。
注意:
连接建立之后,服务器端的套接字对象调用getInetAddress()方法可以获取一个InetAddress对象,该对象含有客户端的IP地址和域名。反之,客户端调用方法可以获得服务器的IP地址和域名。
代码示例:
①:手动创建客户端与服务器通信:
public class Service{
public static void main(String[] args) throws IOException {
ServerSocket ssc=new ServerSocket(9999);
System.out.println("服务器端开启:IP为"+ssc.getInetAddress().getHostAddress());
System.out.println("端口 号为:"+ssc.getLocalSocketAddress());
System.out.println("正在等待有缘人...");
Socket clientsocket=ssc.accept();//返回一个Socket对象用于和客户端连接,并且阻塞
System.out.println("连接客户端成功,客户端IP为"+clientsocket.getInetAddress() );
System.out.println("客户端的端口号为:"+clientsocket.getPort());
InputStream input=clientsocket.getInputStream();
OutputStream output= clientsocket.getOutputStream();
String msg= new String("服务器连接成功connecting success");
//发送字符串长度
output.write(msg.getBytes().length);
output.write(msg.getBytes());
output.flush();//刷新缓冲, 管道强制刷出
}
}
public class Client {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",9999);
InputStream input=socket.getInputStream();
OutputStream output=socket.getOutputStream();
//将传入的字符数构造字节数组对象
int msglength=input.read();
System.out.println("消息长度是"+msglength);
byte[] msgbytes=new byte[msglength];
input.read(msgbytes);
String getmsg =new String(msgbytes);
System.out.println("服务器传来数据:"+getmsg);
}
}
服务器:
客户端:
②:用telnet客户端和服务器通信:
public class Service {
public static void main(String[] args) throws IOException {
ServerSocket ssc=new ServerSocket(9999);
System.out.println("服务器端开启:IP为"+ssc.getInetAddress().getHostAddress());
System.out.println("端口 号为:"+ssc.getLocalSocketAddress());
System.out.println("正在等待有缘人...");
Socket clientsocket=ssc.accept();//返回一个Socket对象用于和客户端连接,并且阻塞
System.out.println("连接客户端成功,客户端IP为"+clientsocket.getInetAddress() );
System.out.println("客户端的端口号为:"+clientsocket.getPort());
InputStream input=clientsocket.getInputStream();
OutputStream output= clientsocket.getOutputStream();
String msg= new String("服务器连接成功connecting success\n");
//发送字符串长度
output.write(msg.getBytes());
while(true) {
int readnum=input.read();
System.out.print((char)readnum);
}
}
}
首先开启服务器端:
使用telnet客户端连接服务器
命令:telnet 127.0.0.1 9999
总结
客户端:
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 9999);//目的服务器地址和端口
Socket socket=new Socket()//创建客户端IP
socket.connect(inetSocketAddress);//连接服务器
服务器端:
ServerSocket serverforclient = new ServerSocket(9999);//server服务器的IP为本机IP
Socket Servsocket = serverforclient.accept();//accept阻塞 等待被连接
//连接成功后返回一个和客户端Socket对象相连接的Socket对象,这个对象驻留在服务器端被使用
UDP通信
套接字是基于TCP协议的网络通信,即客户端程序和服务器程序是有连接的,双方的信息是通过程序的输入、输出流来交互的,使得接收方收到的信息的顺序和发送方发送信息的顺序完全相同,就像生活中双方使用电话进行信息交互一样。
基于UDP的通信和基于TCP的通信不同,基于UDP的信息传递更快,但不提供可靠性保证。也就是说数据在传输时,用户无法知道数据能否正确到达目的地主机,也不能确定数据到达目的地的顺序和发送的顺序相同。
基于UDP通信的基本模式是:
- 将数据打包,称为数据报包,然后将数据包发送目的地。
- 接收发来的数据包,然后查看数据包中的内容。
发送数据包
用DatagramPacket类将数据打包。
常用的构造方法如下:
接收数据包