1.网络基础知识
1.1 Internet与OSI
ISP(因特网服务提供商)
按照作用范围:广域网、城域网、局域网和个人区域网
OSI:物理层、数据链路层、网络层、运输层、会话层、表示层、应用层
1.2 IP地址与端口号
IPv4与IPv6
1.3 UDP与TCP
2. Socket编程
2.1认识socket
套接字,用于描述IP地址和端口,在Java环境中通常是基于TCP/IP的,使用socket将TCP/IP包发送到指定IP地址。
客户端发送数据,服务端接受数据。
交互的5个步骤:
- 服务器指定监听的端口号;
- 客户端指定服务端的IP地址和端口号;
- 客户端向服务器发送请求;
- 服务器经过端口匹配后,接收客户端发送的请求,并给予客户端反馈;
- 客户端接收到服务器的反馈后,完成客户端的其他操作。
2.2 InetAddress类
主要用于IP的使用和相关的操作:
序号 | 方法名 | 说明 |
1 | String getHostName() | 返回主机名 |
2 | static InetAddress getLocalHost() | 静态方法,返回本地主机名和IP地址 |
3 | String getHostAddress() | 返回字符串格式的原始IP地址 |
4 | static InetAddress getByName(String host) | 返回给主机名的IP地址 |
5 | static InetAddress[] getAllByName(String host) | 返回给主机名的所有IP地址组成的数组 |
6 | boolean is Reachable(int timeout) | 返回指定地址是否可达 |
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Scanner; //获得服务器对应IP地址 public class Demo12_2 { public static void main(String[] args) { Scanner sc1 = new Scanner(System.in); System.out.println("请输入服务器网址:"); String adress = sc1.next(); try { InetAddress iadressAddress = InetAddress.getByName(adress); System.out.println(iadressAddress); } catch (UnknownHostException e) { // TODO: handle exception e.printStackTrace(); } } }
请输入服务器网址:
www.baidu.com
www.baidu.com/183.232.231.172
2.3基于UDP的socket程序
不可靠的传输协议,适用于少量的数据并且要求传输速度快的情况,使用的类主要有DatagramSocket和DatagramPacket。
序号 | DatagramSocket | DatagramPacket | ||
方法名 | 说明 | 方法名 | 说明 | |
1 | DatagramSocket() | 构造方法,端口自动分配 | DatagramPacket(byte[] buf,intlength) | 构造方法,指定存储包存储空间与长度 |
2 | DatagramSocket(int port) | 构造方法,设置端口号 | DatagramPacket(byte[] buf,int length,InetAddress addr,int port ) | 构造方法,指定空间、尺度、IP地址和端口号 |
3 | DatagramSocket(int port,InetAddress addr) | 构造方法,指定端口号及IP | DatagramPacket(InetAddress addr,int port ) | 构造方法,指定端口号与IP地址 |
4 | public void send(DatagramPacket P) | 发生数据 | public byte[] getData() | 获取数据 |
5 | public void receive(DatagramPacket P) | 接收数据 | public int getLength() | 获取接收过来的数据长度 |
6 | public void close() | 关闭 | public void setData(byte[] buf) | 设置传输的数据 |
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; //基于UDP的socket程序_客户端 public class Demo12_3 { public static void main(String[] args) { DatagramSocket dgs01 = null; try { dgs01 = new DatagramSocket(); Scanner sc01 = new Scanner(System.in); System.out.println("请输入要发送给服务器端的数据:"); String str01 = sc01.next(); DatagramPacket dgp01 = new DatagramPacket(str01.getBytes(), str01.length(),InetAddress.getLocalHost(),8888); dgs01.send(dgp01); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { dgs01.close(); } } }
import java.net.DatagramPacket; import java.net.DatagramSocket; //基于UDP的socket程序——服务器端 public class Demo12_4 { public static void main(String[] args) { DatagramSocket dgs02 = null; try { dgs02 = new DatagramSocket(8888); System.out.println("服务器启动中:"); byte[] buf = new byte[1024]; DatagramPacket dgp02 = new DatagramPacket(buf, 1024); dgs02.receive(dgp02); String str02 = new String(dgp02.getData(), 0, dgp02.getLength()); System.out.print(str02); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { dgs02.close(); } } }
2.4基于TCP的socket程序
可靠的传输协议,需要使用ServerSocket类和Sockeet类.
序号 | ServerScoket类(服务器端) | Socket类(客户端) | ||
方法 | 说明 | 方法 | 说明 | |
1 | ServerSocket() | 构造方法 | Socket(String hostName,int port) | 构造方法,指定计算机名和端口号 |
2 | ServerSocket(int port) | 构造方法,设置端口号 | public int getPort() | 获得端口号 |
3 | public Socket accept() | 接收客户端的请求 | public InputStream getInputStream() | 获得输入流 |
4 | public void close() | 关闭ServerSocket对象 | public OutputStream getOutputStream() | 获得输出流 |
5 | public void close() | 关闭socket对象 |
2.5基于TCP的多线程socket程序
服务器端:
import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; //多线程类 public class OddThread implements Runnable{ Socket s; InputStream instream; OutputStream outstream; public OddThread(Socket s) { // TODO Auto-generated constructor stub this.s = s; } public void run() { try { instream = s.getInputStream(); outstream = s.getOutputStream(); byte[] buf = new byte[1024]; int len = instream.read(buf); String str01 = new String(buf, 0, len); String str02 = ""; if(Integer.valueOf(str01) % 2 == 0) { str02 = "您输入的是偶数"; } else { str02 = "你输入的是奇数"; } outstream.write(str02.getBytes()); outstream.flush(); outstream.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { this.close(); } } //关闭流close public void close() { try { instream.close(); outstream.close(); s.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
import java.net.ServerSocket; import java.net.Socket; //服务器端-启动服务器 public class Demo12_5 { public static void main(String[] args) { ServerSocket ss = null; try { ss = new ServerSocket(6666); System.out.println("启动服务器。。。"); while (true) { Socket socket = ss.accept(); Thread t1 = new Thread(new OddThread(socket)); t1.start(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { try { ss.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } }
客户端:
import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner; //客户端 public class Demo12_6 { public static void main(String[] args) { try { while (true) { Socket s = new Socket("127.0.0.1", 6666); OutputStream outstream = s.getOutputStream(); InputStream inStream = s.getInputStream(); Scanner sc01 = new Scanner(System.in); System.out.println("请输入一个数:"); String strinput = sc01.next(); outstream.write(strinput.getBytes()); outstream.flush(); byte[] buf = new byte[1024]; int len = inStream.read(buf); String rs = new String(buf, 0, len); System.out.println("反馈结果:" + rs); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }