网络通信三要素:
1.IP地址;
网络上每台计算机的唯一身份证;
2.端口号;
计算机应用的标阿拉伯代表
1-1024是计算机系统使用及保留的端口;
0-65536是有效端口;
常见端口:http(80),mysql(3306),oracle(1521)
3.通信协议;
网络计算机通信规则
TCP协议;
UDP协议
TCP/IP参考模型:
Transfer Control Protocol(传输控制协议);
面向连接保证可靠传输;
IP层负责网络主机定位;
TCP层负责提供面向应用的可靠性或者非可靠的数据传输机制;
通过此协议传输得到有序无差错数据流。
通过两个socket建立连接,因此该协议多了个连接时间
TCP/IP是基于连接的协议;
HTTP,FTP,Telnet都通过此协议传输;
是一个可靠的协议
接收和输出端能正确大量传输数据。
检验数据正确性占用计算机处理时间和网络带宽,传输效率不高;
OSI model------TCP/IP model
应用层----------HTTP协议,FTP协议
表示层----------HTTP协议,FTP协议
会化层----------HTTP协议,FTP协议
传输层----------UDP协议,TCP协议
网络层----------IP协议
数据链路层-----XXXXXXXXXXX
物理层----------XXXXXXXXXXX
IP地址的分类:
JAVA中的地址类,用于指定网络ID,并在网络ID和主机ID之间提供分隔方法;
IANA 负责分配A , B , C 类网络地址,具体主机地址由机构组织自行分配;
InetAddress的基本套路:
package cn.net01;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class Test02 {
public static void main(String[] args) throws UnknownHostException {
// 通过IP地址构建InetAddress对象
byte[] ip = new byte[] {(byte) 192,(byte) 168,7,(byte)189};
InetAddress ip1 = InetAddress.getByAddress(ip);
System.out.println(ip1.toString());
//获取此IP地址的主机名;
System.out.println(ip1.getHostName());
//返回文本显示中的IP地址字符串;
System.out.println(ip1.getHostAddress());
// 给定名称www.baidu.com 获取地址
InetAddress ip3 = InetAddress.getByName("www.baidu.com");
System.out.println(ip3.toString());
InetAddress[] ips = InetAddress.getAllByName("www.baidu.com");
System.out.println(Arrays.toString(ips));
}
}
TCP/IP编程的套路
需求:服务器向客户端完成一次单向通信;
服务器端
package cn.net02;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server01 {
public static void main(String[] args){
System.out.println("server running....");
// 【1】创建一个流 套接字 并将其连接到指定 IP 地址的指定端口;
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8000);
} catch (IOException e) {
e.printStackTrace();
}
// 【2】等待客户端链入
Socket clientSocket = null;
try {
// accept 阻塞式方法
clientSocket = serverSocket.accept();
System.out.println("客户端"+clientSocket.getInetAddress().getHostAddress()+"链入");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 【3】服务器给客户端发信息
OutputStream out = null;
try {
out = clientSocket.getOutputStream();
String msg = "hello!";
byte[] buf = msg.getBytes();
out.write(buf);
clientSocket.shutdownOutput();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
import java.net.Socket;
import java.net.UnknownHostException;
import com.sun.org.apache.bcel.internal.generic.NEW;
public class Client01 {
public static void main(String[] args) {
System.out.println("client running...");
// 【1】创建客户端socket
Socket socket=null;
try {
socket = new Socket("192.168.7.194",8000);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 【2】接收服务器发来的信息
InputStream in = null;
try {
in = socket.getInputStream();
byte[] buf = new byte[4];
int len;
StringBuilder sb = new StringBuilder();
while( (len=in.read(buf)) != -1) {
sb.append(new String(buf,0,len));
}
System.out.println("来自服务器的消息:"+sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
常见异常
1.端口被占用;
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at cn.net02.Server01.main(Server01.java:15)
Exception in thread "main" java.lang.NullPointerException
at cn.net02.Server01.main(Server01.java:24)
2.服务器未启动;
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
…
3.SocketTimeoutException 连接超时异常。
需求:服务器向客户端双向通信;
服务器端
package cn.net03;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server01 {
public static void main(String[] args) throws IOException {
System.out.println("server running....");
ServerSocket serverSocket = new ServerSocket(8000);
Socket clientSocket = serverSocket.accept();
// send msg to client
OutputStream out = clientSocket.getOutputStream();
String msg = "hello client";
DataOutputStream dos = new DataOutputStream(out);
dos.writeUTF(msg);
clientSocket.shutdownOutput();
// receive msg2 from client
InputStream in = clientSocket.getInputStream();
DataInputStream dis = new DataInputStream(in);
String msg2 = dis.readUTF();
System.out.println("来自客户端消息:"+msg2);
clientSocket.shutdownInput();
dos.close();
out.close();
in.close();
dis.close();
}
}
客户端
package cn.net03;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.print.Doc;
public class Client01 {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("client running...");
Socket socket = new Socket("127.0.0.1",8000);
// receive msg from server
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
String msg = dis.readUTF();
System.out.println(msg);
socket.shutdownInput();
// send msg to server
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
String msg2 = "hello server";
dos.writeUTF(msg2);
socket.shutdownOutput();
in.close();
dis.close();
out.close();
dos.close();
}
}