Socket编程

一、概述

socket是应用层与传输层的一个抽象(不是协议),将复杂的TCP/IP协议隐藏在Socket接口之后,只对应用层暴露简单的接口。
socket是一个主机连接双发的两端。

二、原理

Socket编程即可基于TCP协议,也可以基于UDP协议。

2.1 基于TCP的Socket编程

TCP是基于字节流的传输层通信协议,所以TCP编程是基于IO流编程。

客户端:
1、创建Socket对象,并指定服务器端应用程序的端口号和服务器端主机的IP地址。
2、使用Socket的对象调用getOutputStream()方法来获取字节输出流对象。
3、调用字节输出流的write(byte[] buf)或者write(int b)向服务器发送指定数据。
4、记得关闭流。

服务器端:
1、创建ServerSocket对象,并指定该应用程序的端口号,端口号必须和客户端指定的端口号一样。
2、使用ServerSocket对象的accept()方法来监听客户端发送过来的请求,返回值为Socket对象。
3、调用Socket对象的getInputStream()方法获取字节输入流对象
4、调用字节输入流对象的read(byte[] buf)或read()方法获取数据。
5、记得关闭流。

2.2 基于UDP的Socket编程

UDP使用数据报进行数据传输,没有客户端与服务器端之分,只有发送方与接收方,要先启动接收方再启动发送发,这样接收端口才能先开启接收端口。

发送方:
1、创建DatagramSocket对象,可以指定应用程序的端口号,也可以不指定。
2、准备需要发送的数据
3、创建DatagramPacket对象,用来对发送的数据进行打包,需要指定发送内容、发送多少、发送到哪里和接收方的端口号四个参数。
4、调用DatagramSocket对象的send()方法发送数据。
5、记得关闭流。

接收方:
1、创建DatagramSocket对象,指定接收方的端口号,这个必须指定。
2、创建一个byte类型数组,用来接收发送方发送过来的数据。
3、创建DatagramPacket对象,准备接收数据。
4、调用DatagramSocket对象的receive()方法用于接收数据。
5、使用String类的构造方法将byte类型的数组中的数据转化成String类型并显示。
6、记得关闭流。

三、实战demo

3.1 基于TCP编程

Server类

package socketEx.tcpDemo_ex01;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        //创建socket,绑定端口
        ServerSocket serverSocket = new ServerSocket(8888);
        //监听端口
        Socket socket = serverSocket.accept();
        //获取输入流,读取客户端信息
        InputStream in = socket.getInputStream();
        //将字节输入转换成字符输入
        InputStreamReader inputStreamReader = new InputStreamReader(in);
        //为输入添加缓冲
        BufferedReader br = new BufferedReader(inputStreamReader);
        //存放客户端输出的数据
        String info = null;
        while((info = br.readLine()) != null){
            System.out.println("我是服务器,客户端的信息为:"+info);
        }
        //关闭输入流
        socket.shutdownInput();

        //服务器输出信息,获取输出流,
        OutputStream out = socket.getOutputStream();
        //包装为打印流
        PrintWriter printWriter = new PrintWriter(out);
        //输出信息
        String serverInfo = "欢迎你";
        //写入打印流
        printWriter.write(serverInfo);
        //刷新缓冲
        printWriter.flush();

        //关闭资源
        serverSocket.close();
        socket.close();
        inputStreamReader.close();
        br.close();
        in.close();

        out.close();
        printWriter.close();


    }
}

Client类

package socketEx.tcpDemo_ex01;

import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        //创建客户端socket,连接指定ip和端口号
        Socket socket = new Socket("127.0.0.1",8888);
        //获取输出流,写输出数据
        OutputStream out = socket.getOutputStream();
        //封装为打印流
        PrintWriter printWriter = new PrintWriter(out);
        //输出内容
        String info = "用户名为:123,密码为:888";
        printWriter.write(info);
        //刷新缓冲,避免缓冲区不满,死锁
        printWriter.flush();
        socket.shutdownOutput();

        //获取输入流,获取服务端信息
        InputStream in = socket.getInputStream();
        //封装成字符流
        InputStreamReader inputStreamReader = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(inputStreamReader);
        //服务端信息
        String serverInfo = null;
        while((serverInfo = br.readLine()) != null){
            System.out.println("服务端的信息为:"+serverInfo);
        }
        socket.shutdownInput();

        //关闭资源
        socket.close();
        out.close();
        printWriter.close();
        in.close();
        inputStreamReader.close();
        br.close();
    }
}

运行结果
在这里插入图片描述

在这里插入图片描述

3.2 基于UDP编程

Server类

package socketEx.udpDemo_ex01;

import java.io.IOException;
import java.net.*;

public class Server {
    public static void main(String[] args) throws IOException {
        //作为接收方,接收数据
        //服务端创建socket,绑定端口(接收方必须绑定端口,发送方可以不绑定)
        DatagramSocket socket = new DatagramSocket(8888);
        //创建数据报,接收客户端信息
        //创建字节数组,指定接收的数据包大小
        byte[] data = new byte[1024];
        //创建数据包
        DatagramPacket packet = new DatagramPacket(data,data.length);
        //接收客户端发送的信息
        //接收到数据之前,会一直阻塞,会把数据存放到packet的data中
        socket.receive(packet);
        //读取数据
        String info = new String(data,0,packet.getLength());
        System.out.println("我是服务端,客户端的信息是:"+info);

        //收到数据后,作为发送方,发送数据
        //定义客户端的ip,端口号,数据,通过上文的pocket获取客户端的ip和port
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        byte[] data2 = "欢迎你".getBytes();
        DatagramPacket packet2 = new DatagramPacket(data2,data2.length,address,port);
        //发送
        socket.send(packet2);

        //关闭资源
        socket.close();
    }
}

Client类

package socketEx.udpDemo_ex01;

import java.io.IOException;
import java.net.*;

public class Client {
    public static void main(String[] args) throws IOException {
        //作为发送方,指定接收方的ip,port,发送的数据data
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8888;
        byte[] data= "用户名:Archie,密码:123".getBytes();
        //创建数据包
        DatagramPacket packet = new DatagramPacket(data,data.length,address,port);
        //发送的信息

        socket.send(packet);

        //作为接收方,接收服务端的数据
        byte[] data2 = new byte[1024];
        DatagramPacket packet2 = new DatagramPacket(data2,data2.length);
        socket.receive(packet2);
        String info2 = new String(data2,0,packet2.getLength());
        System.out.println("我是客户端,服务端的信息:"+info2);

        //关闭资源
        socket.close();
    }
}

运行结果
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值