Socket学习笔记

Socket笔记

TCP/IP协议

  • TCP/IP是目前世界上应用最为广泛的协议,是以TCP和IP为基础的不同层次上多个协议的集合
  • TCP:Transmission Control Protocol 传输控制协议
  • IP:Internet Protocol 互联网协议

TCP/IP五层协议

graph TD
A[应用层]-->B
B[传输层]-->C
C[网络层]-->D
D[数据链路层]-->E[物理层]
应用层协议:
  • HTTP 超文本传输协议
  • FTP 文件传输协议
  • SMTP 简单邮件传输协议
  • Telent 远程登陆协议
传输层协议:
  • TCP/IP协议

端口

  • 用于区分不同应用程序
  • 端口范围为065535,其中01023为系统所保留
  • IP地址和端口号组成了所谓的Socket,Socket是网络上运行程序之间双向通讯链路的终结点,是TCP和UDP的基础
  • http:80 ftp:21 telent:23

JAVA中的网络支持

针对网络通信的不同层次,Java提供的网络功能有4大类:

  1. InetAddress:用于标识网络上的硬件资源。
  2. URL:统一资源定位符 通过URL可以直接读取或写入网络上的数据。
  3. Sockets:使用TCP协议实现网络通信的Socket相关的类。
  4. Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信

InetAddress类

实例化
InetAddress ia = InetAddress.getLocalHost();
方法
ia.getHostName() 获取主机名
ia.getHostAddress() 获取IP地址
ia.getAddress() 获取字节数组的IP地址

URL类

  1. URL(Uniform Resource Locator)统一资源定位符,标识Internet上的某一资源的地址
  2. URL由两部分组成:协议名称和资源名称,中间用冒号隔开

常用方法

  1. getProtocol() 获取协议
  2. getHost() 获取主机名
  3. getPort() 获取端口号 //若果未指定端口号,返回-1为不同协议默认端口号
  4. getPath() 获取文件路径
  5. getFile() 获取文件名
  6. getRef() 获取相对路径
  7. getQuery() 获取查询字符串

基于TCP协议实现网络通信的类

客户端的Socket类
服务端的ServerSocket类

Scoket通信模型

建立连接:

sequenceDiagram
Server->>Client: 建立服务端倾听socket
Client->>Server: 创建连接socket向服务端发送请求
Server->>Client: 等待并接受连接请求
Server->>Client: 接受请求后连接socket

开始通信:

sequenceDiagram
Server->>Client: InputStream/OutputStream进行通信
Client->>Server: InputStream/OutputStream进行通信

结束通信

sequenceDiagram
Server->>Client: 关闭socket及相关资源
Client->>Server: 关闭socket及相关资源

服务端示例

public static void main(String[] args){
    //创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
    ServerSocket serverSocket=new ServerSocket(8888);
    //调用accept()方法开始监听,等待客户端的连接
    System.out.println("****服务器即将启动,等待客户端的连接****");
    Socket socket=serverSocket.accept();
    //获取输入流,并读取客户端信息
    InputStream is=socket.getInputStream();//字节输入流
    InputStreamReader isr=new InputStreamReader(is);//将字节流包装为字符流
    BufferedReader br=new BufferedReader(isr);//为输入流添加缓冲
    String info=null;
    while((info=br.readLine())!=null)
    {
        //循环读取客户端的信息
        System.out.println("我是服务器,客户端说:"+info);
    }
    //获取输出流,响应客户端的请求
    OutputStream os=socket.getOutputStream();
    PrintWriter pw=new PrintWriter(os);//包装为打印流
    pw.write("欢迎您!");
    pw.flush();//调用flush()方法刷新缓冲输出
    socket.shotdownInput();//关闭输入流
    br.close();
    isr.close();
    is.close();
    pw.close();
os.close();
    socket.close();
    serverSocket.close();
}

客户端示例

public static void main(String[] args){
    //创建客户端Socket,指定服务器地址和端口
    Socket socket=new Socket("IP地址","端口号");
    //获取输出流,向服务器发送信息
    OutputStream os=socket.getOutputStream();//字节输出流
    PrintWriter pw=new PrintWriter(os);//将输出流包装为打印流
    pw.write("用户名:admin;密码:123");
    pw.flush();
    InputStream is=socket.getInputStream();
    BufferedReader br=new BufferedReader(new InputStreamReader(is));
    String line;
    while((line=br.readerline()!=null)
    {
    System.out.println("我是客户端,服务器说:"+line);
    }
    socket.shutdownOutput();//关闭输出流
    //关闭相应的资源
    pw.close();
    os.close();
    socket.close();
}

多客户端连接示例

应用多线程来实现服务器与多客户端之间的通信
基本步骤
1.服务器端创建ServerSocket,循环调用accept()等待客户端连接
2.客户端创建一个socket并请求和服务器端连接
3.服务器端接收客户端请求,创建socket与该客户建立专线连接
4.建立连接的两个socket在一个单独的线程上对话
5.服务器端继续等待新的连接

服务器线程处理类

public class ServerThread extends Thread
{
  //和本线程相关的socket
  Socket socket=null;
  public ServerThread(Socket socket)
{
  this.socket=socket;
}
//线程执行的操作,响应客户端的请求
public void run()
{
//获取输入流,并读取客户端信息
//获取输出流,反馈信息给客户端
}
}

服务器的修改

Socket socket=null;
//记录客户端的数量
int count=0;
//循环监听等待
while(true)
{
    //调用accept()方法开始监听,等待客户端的连接
    socket=serverSocket.accept();
    //创建一个新的线程
    ServerThread serverThread=new ServerThread(socket);
    //启动线程
    serverThread.start();
    count++;
    System.out.println(count);
    //获取当前客户端的IP
    InetAddress address=socket.getInetAddress();
    System.out.println("当前客户端的IP:"+address.getHostAddress());
}

基于UDP的Socket编程

服务器端实现步骤:

  1. 创建DatagramSocket
  2. 创建Datagrampacket
  3. 接受客户端发送的数据信息
  4. 读取数据

客户端实现步骤:

  1. 定义发送信息
  2. 创建DatagramPacket,包含将要发送的信息
  3. 创建DatagramSocket
  4. 发送数据

服务器端示例:

服务器端,实现基于UDP的用户登录

//创建服务器端DatagramSocket,指定端口
DatagramSocket socket=new DatagramSocket(8800);
//创建数据报,用于接收客户端发送的数据
byte[]data=new byte[1024];//创建字节数组,指定接收的数据报的大小
DatagramPacket packet=new DatagramPacket(data,data.length);
//接收客户端发送的数据
socket.receive(packet);//此方法在接收到数据之前会一直阻塞
//读取数据
String info=new String(data,0,packet.getLength());
System.out.print("我是服务器,客户端说:"+info);

//定义客户端的地址、端口号、数据
IneetAddress address=packet.getAddress();
int port=packet.getPort();
byte[]data2="欢迎你!".getBytes();
//创建数据报,包含响应的数据信息
DatagramPacket packet2=new DatagramPacket(data2,data2.length,address,port);
//响应客户端
socket.send(packet2);
//关闭资源
socket.close();

客户端示例:

//定义服务器的地址、端口号、数据
InetAddress address=InetAddress.getByName("localhost");
int port=8800;
byte[]data="用户名:admin;密码:123".getBytes();
//创建数据报,包含发送的数据信息
DatagramPacket packet=new DatagramPakcet(data,data.length,address,port);
//创建DatagramSocket的对象
DatagramSocket socket=new DatagramSocket();
//向服务器发送数据报
socket.send(packet);

//接收服务器发送过来的消息
//创建数据报,用于接收服务器响应的数据
byte[]data2=new byte[1024];
DatagramPacket packet2=new DatagramPacket(data2,data2.length);
//接收服务器响应的数据
socket.receive(packet2);
//读取数据
String reply=new String(data2,0,packet2.getLength());
System.out.println("我是客户端,服务器说:"+reply);
//关闭资源
socket.close();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值