单线程网络编程2:Socket套接字编程Demo

本文介绍了一个简单的Java Socket编程案例,包括服务器端和客户端的实现过程。服务器端通过ServerSocket监听指定端口,接收并处理客户端发来的请求;客户端则通过Socket连接服务器,并发送消息,最后接收服务器反馈。

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

1.服务器端

package socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketTest extends Thread {
	private static int count;

	private static void countAdd() {
		count++;
	}

	public static int getCount() {
		return count;
	}

	private static ServerSocket serverSocket;

	public static void startServer(int port) throws IOException {
		// 1.服务器端创建ServerSocket对象,指定服务器的端口号,监听该端口,构造方法有
		// 01ServerSocket(int port):指向某端口,默认该端口最多可以处理50个连接请求
		// 02ServerSocket(int port,int backlog):指向某端口,指定该端口最多可以处理backlog个连接请求
		// 启动服务器监听端口
		serverSocket = new ServerSocket(port);
		serverSocket.setSoTimeout(1000 * 60 * 10);
		StringBuilder startMsg = new StringBuilder();
		startMsg.append("我是服务器:" + serverSocket.getLocalSocketAddress() + "\n");
		startMsg.append("我的端口号:" + serverSocket.getLocalPort() + "\n");
		startMsg.append("我已启动监听服务\n");
		startMsg.append("服务时长:" + serverSocket.getSoTimeout() / 60 / 1000
				+ " min\n");
		System.out.println(startMsg.toString());
	}

	public ServerSocketTest() {

	}

	@Override
	public void run() {	
		while (true) {
			// 2.监听端口请求
			countAdd();
			System.out.println("----RequestId:" + String.format("%06d", getCount())
					+ "---------\n准备好监听服务...");
			try {
				Socket socket = serverSocket.accept();
				// 休眠5秒,模仿耗时操作
				Thread.sleep(5000);
				StringBuilder clientHostMsg = new StringBuilder();
				clientHostMsg.append("客户端主机:" + socket.getRemoteSocketAddress()
						+ "\n");
				clientHostMsg.append("客户端端口:" + socket.getPort() + "\n");
				System.out.println(clientHostMsg.toString());
				// 3.打开Socket关联的输出流/输入流通道
				// 计算机之间的通信使用的是字节流,因此需要创建相应流对象
				// 服务器端的输出流将用于向Socket通道写数据,数据发送到客户端
				// 服务器端的输入流将用于从Socket通道读数据,数据来自客户端
				DataInputStream is = new DataInputStream(socket
						.getInputStream());
				DataOutputStream os = new DataOutputStream(socket
						.getOutputStream());
				// 4.读取输入流内容
				System.out.println("我是服务器,接收到客户端信息是:" + is.readUTF());
				// 5.向输出流通道写入内容
				String infoToClient = "小明,欢迎你连接服务器<Boss>!";
				os.writeUTF(infoToClient);

				// 6.关闭所有的流和套接字
				is.close();
				os.close();
				socket.close();
			}catch (InterruptedException ie) {
				ie.printStackTrace();
			}catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println("服务端流和套接字已关闭\n");
		}
	}

	/**
	 * 1.服务器端创建ServerSocket对象,指定服务器的端口号,监听该端口
	 * 2.调用ServerSocket对象的accept()方法,等待客户端触发通信(即向服务器端口发送数据)
	 * 该方法一直被阻塞,直到客户端触发了通信,该方法给每一个客户端返回一个Socket套接字对象。 3.打开Socket关联的输出流/输入流通道
	 * 4.服务器读取内容自Socket套接字的数据输入通道(即输入流) 5.服务器写入内容到Socket套接字的数据输出通道(即输出流)
	 */
	public static void main(String[] args) throws IOException {
		// 启动服务
		ServerSocketTest.startServer(8080);
		// 创建服务器对象
		Thread serverThread = new ServerSocketTest();
		// 运行服务:循环持续监听,同步阻塞式服务(单线程,多客户端请求时排队处理)
		serverThread.run();
	}

}

2.客户端

package socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientSockerTest {

	/**
	 * 1.客户端创建Socket连接,指定服务器的地址和端口号,请求与服务器的该端口进行连接
	 * 2.打开Socket关联的输出流/输入流通道
	 * 3.客户端写入内容到Socket套接字(指定服务器的指定端口)的数据输出通道(即输出流)
	 * 4.客户端读取内容自Socket套接字的数据输入通道(即输入流)
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		//1.客户端创建Socket连接,指定服务器的地址和端口号,请求与服务器的该端口进行连接
		//Socket socket=new Socket(serverName, port)
		//serverName为"服务器域名或IP地址",port为服务器服务端口号,取值0-65535
		Socket socket=new Socket("localhost", 8080);
		StringBuilder serverHostMsg = new StringBuilder();
		serverHostMsg.append("我已连上服务端主机\n");
		serverHostMsg.append("服务端主机:"+socket.getRemoteSocketAddress()+"\n");
		serverHostMsg.append("服务端端口:"+socket.getPort()+"\n");
		System.out.println(serverHostMsg.toString());
		
		//2.打开Socket关联的输入和输出流通道,即在服务器的该指定端口与客户端(的某个浮动端口)之间建立数据传输通道
		//计算机之间的通信使用的是字节流,因此需要创建相应流对象
		//客户端的输出流将用于向Socket通道写数据,数据发送到服务器端
		//客户端的输入流将用于从Socket通道读数据,数据来自服务器端
		DataOutputStream os=new DataOutputStream(socket.getOutputStream());
		DataInputStream is=new DataInputStream(socket.getInputStream());
		
		//3.通过输出流/输入流通道写入/读取内容到/自服务器
		//3.1向输出流通道写入内容:调用DataOutputStream的writeUTF方法
		String infoToServer="我是客户端小明,请求连接服务器<Boss>...";
		os.writeUTF(infoToServer);
		//3.2从输入流通道读取来自服务器的响应
		System.out.println("服务器<Boss>的响应是:"+is.readUTF());
		//4.关闭所有流通道
		is.close();
		os.close();
		
		//5.关闭套接字,服务器与客户端的所有联系通道也都被关闭
		//If this socket has an associated channel then the channel is closed as well
		socket.close();
		System.out.println("客户端流和套接字已关闭");
	}
}

3.运行效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值