java网络编程小白教程
1 网络编程
1.1 网络
把多台终端(计算机)通过物理线路连接起来,形成网络。便于交换数据、共享信息、组成更强大的逻辑体。
1.1.1 网络通信三要素
【1】IP地址:唯一标识网络上的每一台计算机
两台计算机之间通信的必备有素
【2】端口号:计算机中应用的标号(代表一个应用程序)
0-1024系统使用或保留端口 ,
有效端口0-65536
常见的端口http协议80端口、mysql(3306) oracle(1521)
【3】通信协议:通信的规则
TCP,UDP
1.1.2 TCP/IP参考模型
|
1.1.3 IP地址分类
|
127.0.0.1 表示本机IP地址
1.2 InetAddress
表示IP地址信息
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());
System.out.println(ip1.getHostName()); 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));
} } |
1.3 TCP编程(A)
案例:服务器向客户端完成一次单向通信
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】创建serversocket 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(); }
} }
|
package cn.net02;
import java.io.IOException; import java.io.InputStream; 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();
} }
|
需求:请发送一张图片到服务器。
需求:c/s模式验证用户名密码。
User序列化是客户端和服务器端的全路径一定要一致。
1.4 UDP编程(B)
需求:客户端A向客户端B发信息
客户端A
package cn.net06;
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner;
public class ClientA { public static void main(String[] args) throws IOException { // 客户端A
DatagramSocket ds = new DatagramSocket(8000); while(true) { //System.out.println("请输入"); Scanner sc = new Scanner(System.in); String msg = sc.nextLine(); // --send msg to ClientB -- System.out.println("开始发送数据:"+msg); byte[] buf = msg.getBytes(); InetAddress toIp = InetAddress.getLocalHost(); DatagramPacket dp = new DatagramPacket(buf, buf.length, toIp, 9000); // 构造一个数据报包socket,通过8000用于发送数据报 ds.send(dp);
// --receive msg from clientA-- byte[] recBuf = new byte[1024]; DatagramPacket recDp = new DatagramPacket(recBuf, recBuf.length); ds.receive(recDp);
String recMsg = new String(recBuf, 0, recDp.getLength()); System.out.println("clientB说:"+recMsg); }
// ds.close(); } }
|
客户端B
package cn.net06;
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.util.Scanner;
public class ClientB { public static void main(String[] args) throws IOException { // 创建一个datagram socket用于结束clientA 传入的数据 DatagramSocket ds = new DatagramSocket(9000); while (true) { // System.out.println("正在接收信息...");
// --receive msg from clinetA-- byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp);
// 从dp中获取接收的内容 String msg = new String(buf, 0, dp.getLength()); System.out.println("clientA说:" + msg);
// --send msg to clientA-- Scanner sc = new Scanner(System.in); String sendMsg = sc.nextLine(); byte[] sendBuf = sendMsg.getBytes(); InetAddress toIp = InetAddress.getLocalHost(); DatagramPacket sendPd = new DatagramPacket(sendBuf, sendBuf.length, toIp, 8000);
// DatagramSocket sendDs = new DatagramSocket(9000); ds.send(sendPd); } } }
|