Socket 编程

本文详细介绍TCP与UDP两种网络编程技术的实现方法,包括客户端与服务器端的代码实例。TCP部分展示了如何通过Socket进行数据的可靠传输,而UDP部分则介绍了如何利用DatagramPacket进行数据包的发送与接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP 编程

  • 传输单位为字节
  • 客户端:socket = new Socket(server, servPort);
  • 服务器:
    • serverSocket = new ServerSocket(serverPort);
    • Socket clientSocket = serverSocket.accept();
  • TCPSocketServer:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class TCPSocketServer {
    public static void main(String[] args) {
        run();
    }

    public static void run() {
        // socket指定端口号,0-65535,不能与其他进程端口号冲突,否则启动会端口占用的错误
        int serverPort = 4700;
        // 创建服务端socket
        ServerSocket serverSocket;
        int receiveMsgSize;
        // 接收字节缓冲数组
        byte[] receiveMsgBuffer = new byte[32];
        try {
            serverSocket = new ServerSocket(serverPort);
            // 处理完一个客户端请求之后再次进入等待状态
            while (true) {
                // 程序执行到这之后,将一直等待客户端连接,直到有客户端接入,代码才继续执行
                System.out.println("服务端已启动,绑定端口" + serverPort);
                Socket clientSocket = serverSocket.accept();
                SocketAddress clientAddress = clientSocket
                        .getRemoteSocketAddress();
                System.out.println("收到客户端连接,ip:" + clientAddress);
                InputStream in = clientSocket.getInputStream();
                OutputStream out = clientSocket.getOutputStream();
                // 接收客户端发来的数据,并原样返回给客户端
                while ((receiveMsgSize = in.read(receiveMsgBuffer)) != -1) {
                    String receivedData = new String(receiveMsgBuffer);
                    System.out.println(receivedData);
                    receivedData = receivedData.toUpperCase();
                    out.write(receivedData.getBytes(), 0, receiveMsgSize);
                }
                // 释放socket资源
                clientSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • TCPSocketClient:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

public class TCPSocketClient {
    public static void main(String[] args) {
        String host = "localhost";
        int port = 4700;
        String sendMsg = "send data from client";
        connect(host, port, sendMsg.getBytes());
    }

    public static void connect(String server, int servPort, byte[] data) {
        // 创建socket对象用于连接服务端socket
        Socket socket = null;
        try {
            socket = new Socket(server, servPort);
            System.out.println("连接服务器并发送数据...");
            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();
            out.write(data);
            // 接收数据
            // 目前收到的总字节长度
            int totalBytesRcvd = 0;
            // 最后一次读取的字节长度
            int bytesRcvd;
            // 将服务器返回消息读到data字节数组中
            while (totalBytesRcvd < data.length) {
                bytesRcvd = in.read(data, totalBytesRcvd, data.length
                        - totalBytesRcvd);
                if (bytesRcvd == -1) {
                    throw new SocketException("连接中断...");
                }
                totalBytesRcvd += bytesRcvd;
            }
            System.out.println("接收的数据:" + new String(data));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {// 关闭socket资源
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

UDP 编程

  • 传输单位为 packet
  • 首先创建 DatagramSocket 对象,再创建 DatagramPacket 对象用于接收或者发送
  • UDPSocketServer:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPSocketServer {
	public static void main(String[] args) {
		receive();
	}

	public static void receive() {
		System.out.println("接收端启动");
		// 接收端
		try {
			// 创建接收方的套接字对象,并与send方法中DatagramPacket的ip地址与端口号一致
			DatagramSocket socket = new DatagramSocket(9001,
					InetAddress.getByName("localhost"));
			// 接收数据的buf数组并指定大小
			byte[] buf = new byte[1024];
			// 创建接收数据包,存储在buf中
			DatagramPacket packet = new DatagramPacket(buf, buf.length);
			// 接收操作,代码会停顿在这里,直到接收到数据包
			socket.receive(packet);
			byte data[] = packet.getData();// 接收的数据
			InetAddress address = packet.getAddress();// 接收的地址
			System.out.println("接收的文本==>" + new String(data));
			System.out.println("接收的ip地址==>" + address.toString());
			System.out.println("接收的端口==>" + packet.getPort());
			// 告诉发送者 接收完毕了
			String temp = "接收端接收完毕了";
			byte buffer[] = temp.getBytes();
			// 创建数据报,指定发送给发送者的socketAddress地址
			DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length,
					packet.getSocketAddress());
			// 发送
			socket.send(packet2);
			// 关闭
			socket.close();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

  • UDPSocketClient:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPSocketClient {

    public static void main(String[] args) {
        send();
    }

    // 发送者发给接收端数据,接收端返回数据给发送者
    public static void send() {
        System.out.println("发送端发送数据");
        // 发送端
        try {
            // 创建发送方的套接字 对象 采用9004默认端口号
            DatagramSocket socket = new DatagramSocket(9004);
            // 发送的内容
            String text = "hello from sender!";
            byte[] buf = text.getBytes();
            // 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
            DatagramPacket packet = new DatagramPacket(buf, buf.length,
                    InetAddress.getByName("localhost"), 9001);
            // 从此套接字发送数据报包
            socket.send(packet);
            // 接收,接收者返回的数据
            displayReceiveInfo(socket);
            // 关闭此数据报套接字。
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 接收数据并打印出来
     *
     * @param socket
     * @throws IOException
     */
    public static void displayReceiveInfo(DatagramSocket socket)
            throws IOException {
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        socket.receive(packet);

        byte data[] = packet.getData();// 接收的数据
        InetAddress address = packet.getAddress();// 接收的地址
        System.out.println("接收的文本==>" + new String(data));
        System.out.println("接收的ip地址==>" + address.toString());
        System.out.println("接收的端口==>" + packet.getPort());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值