Java中网络编程之TCP协议

简介:

一、TCP的基本概念

TCP是专门设计用于在不可靠的英特网上提供可靠的、端到端的字节流通信的协议,是一个面向连接的协议,TCP连接是字节流而非报文流。UDP和TCP各有65536个端口号互不影响。

 

二、单线程服务端

以下代码只能实现服务端和客户端的同步对话。服务端处理完一个客户端请求,才会处理另一个客户端请求。服务器端的输出效果是Client1阻塞20秒,Client2不会执行。必须等Client1阻塞结束之后,Client2才会执行。该例子可用来学习TCP的基本语法。

/**
 * TCP客户端1
 * 
 * @author 徐越
 * 
 */
public class Client1
{
	public static void main(String[] args) throws Exception
	{
		Socket socket = new Socket("127.0.0.1", 8821);
		OutputStream os = socket.getOutputStream();
		String msg = "我是徐越1";
		Thread.sleep(20000);
		os.write(msg.getBytes());
		os.flush();
		os.close();socket.close();
	}
}


/**
 * TCP客户端2
 * 
 * @author 徐越
 * 
 */
public class Client2
{
	public static void main(String[] args) throws Exception
	{
		Socket socket = new Socket("127.0.0.1", 8821);
		OutputStream os = socket.getOutputStream();
		String msg = "我是徐越2";
		os.write(msg.getBytes());
		os.flush();
		os.close();socket.close();
	}
}

/**
 * 单线程TCP服务端
 * 
 * @author 徐越
 * 
 */
public class Server
{
	public static void main(String[] args) throws Exception
	{
		// 创建端口为8821的TCP服务器端对象
		// 8821是服务器端的端口号而客户端从某端口A连到8821,端口A是随机的
		ServerSocket serverSocket = new ServerSocket(8821);
		while (true)
		{
			// 若无客户端发送请求则线程在此阻塞,方法不继续执行
			Socket socket = serverSocket.accept();
			System.out.println("connected");
			InputStream instream = socket.getInputStream();
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			int len = 0;
			byte[] buffer = new byte[1024];
			while ((len = instream.read(buffer)) != -1)
			{
				bos.write(buffer, 0, len);
			}
			instream.close();
			bos.flush();
			bos.close();
			String msg = bos.toString();
			System.out.println("客户端的IP:" + socket.getInetAddress().getHostAddress());
			System.out.println("客户端的端口:" + socket.getPort());
			System.out.println("客户端的信息:" + msg);
		}
	}
}


执行结果

connected
客户端的IP:127.0.0.1
客户端的端口:3775
客户端的信息:我是徐越1
connected
客户端的IP:127.0.0.1
客户端的端口:3787
客户端的信息:我是徐越2

 

三、多线程服务器

在实际应用中是在服务器上运行一个永久的程序,接收来自其他多个客户端的请求,提供相应的服务。需要利用多线程实现多客户机制。服务器在指定的端口上监听是否有客户请求,一旦监听到就会启动一个专门的服务线程来响应该请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。只要将服务端为如下代码,Client1和Client2就会异步执行。

/**
 * 多线程服务端0
 * 
 * @author 徐越
 * 
 */
public class MultiThreadServer0
{
	// 端口号
	private int port = 8821;
	// 服务端
	private ServerSocket serverSocket;

	public MultiThreadServer0() throws IOException
	{
		// 创建服务器端
		serverSocket = new ServerSocket(port);
		System.out.println("服务器启动");
	}

	public void service()
	{
		while (true)
		{
			Socket socket = null;
			try
			{
				// 客户端进行连接时会触发accept方法从而建立连接
				socket = serverSocket.accept();
				new MultiThreadHandler(socket).start();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws IOException
	{
		new MultiThreadServer1().service();
	}
}

/**
 * 多线程处理类
 */
class MultiThreadHandler extends Thread
{
	private Socket socket;

	public MultiThreadHandler(Socket socket)
	{
		this.socket = socket;
	}

	private BufferedReader getReader(Socket socket) throws IOException
	{
		InputStream socketIn = socket.getInputStream();
		// InputStreamReader为转换流
		// InputStream本是字节流,现加一个Reader,表示用字符流的方式读取字节流
		InputStreamReader isr = new InputStreamReader(socketIn);
		return new BufferedReader(isr);
	}

	public void run()
	{
		try
		{
			BufferedReader br = getReader(socket);
			String msg = null;
			while ((msg = br.readLine()) != null)
			{
				System.out.println("客户端的IP:" + socket.getInetAddress().getHostAddress());
				System.out.println("客户端的端口:" + socket.getPort());
				System.out.println("客户端的信息:" + msg);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (socket != null)
				{
					socket.close();
				}
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}


/**
 * 多线程服务端1
 */
public class MultiThreadServer1
{
	// 端口号
	private int port = 8821;
	// 服务端
	private ServerSocket serverSocket;
	// 线程池
	private ExecutorService executorService;
	// 单个CPU线程池大小
	private final int POOL_SIZE = 10;

	public MultiThreadServer1() throws IOException
	{
		// 创建服务器端
		serverSocket = new ServerSocket(port);
		// 获取当前系统的CPU数目
		int cpuNums = Runtime.getRuntime().availableProcessors();
		// 根据系统资源情况灵活定义线程池大小
		executorService = Executors.newFixedThreadPool(cpuNums * POOL_SIZE);
		System.out.println("服务器启动");
	}

	public void service()
	{
		while (true)
		{
			Socket socket = null;
			try
			{
				// 客户进行连接就会触发accept方法从而建立连接
				socket = serverSocket.accept();
				// 调用线程池操作
				executorService.execute(new Handler(socket));
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws IOException
	{
		new MultiThreadServer1().service();
	}

}

/**
 * 多线程处理类
 */
class Handler implements Runnable
{
	private Socket socket;

	public Handler(Socket socket)
	{
		this.socket = socket;
	}

	private BufferedReader getReader(Socket socket) throws IOException
	{
		InputStream socketIn = socket.getInputStream();
		// InputStreamReader为转换流
		// InputStream本是字节流,现加一个Reader,表示用字符流的方式读取字节流
		InputStreamReader isr = new InputStreamReader(socketIn);
		return new BufferedReader(isr);
	}

	public void run()
	{
		try
		{
			BufferedReader br = getReader(socket);
			String msg = null;
			while ((msg = br.readLine()) != null)
			{
				System.out.println("客户端的IP:" + socket.getInetAddress().getHostAddress());
				System.out.println("客户端的端口:" + socket.getPort());
				System.out.println("客户端的信息:" + msg);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (socket != null)
				{
					socket.close();
				}
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}

 

两个多线程服务端执行结果相同

服务器启动
客户端的IP:127.0.0.1
客户端的端口:3931
客户端的信息:我是徐越2
客户端的IP:127.0.0.1
客户端的端口:3928
客户端的信息:我是徐越1


参考地址:http://www.2cto.com/kf/201209/158518.html

目录
相关文章
|
8月前
|
网络协议 Java
Java TCP通信详解
TCP(Transmission Control Protocol)是一种面向连接的、可靠的网络传输协议,它提供了端到端的数据传输和可靠性保证。TCP通信适用于对数据传输的可靠性和完整性要求较高的场景,如文件传输、网页浏览等。本文将详细介绍Java中如何使用TCP协议进行网络通信,包括TCP套接字、服务器和客户端的创建、数据传输等。
134 0
|
2月前
|
网络协议 Java
Java基于TCP的网络编程
Java基于TCP的网络编程
|
8月前
|
网络协议 数据处理 数据安全/隐私保护
Java_TCP和UDP协议的联系与区别
Java_TCP和UDP协议的联系与区别
105 0
|
9月前
|
网络协议 Java
Java TCP和UDP网络通信协议的详解
Java TCP和UDP网络通信协议的详解
60 0
|
8月前
|
网络协议 Java
Java通信程序TCP
Java通信程序TCP
28 0
|
网络协议 Java
Java基础进阶网络编程-TCP和UDP协议
Java基础进阶网络编程-TCP和UDP协议
Java基础进阶网络编程-TCP和UDP协议
|
网络协议 Java
Java-TCP网络编程
Java语言的基于套接字编程分为服务端编程和客户端编程,其通信模型如图所示:
121 0
|
存储 网络协议 Java
【Java】网络编程--Socket与TCP网络通信编程
文章目录 写在前面 1 Socket 2 TCP网络通信编程 2.1 TCP字节流编程 2.1.1 案例:客户端发送数据,服务端接收并显示 2.1.2 案例进阶:双向通信 2.2 TCP字符流编程 2.3 网络上传文件
【Java】网络编程--Socket与TCP网络通信编程
|
网络协议 Java
Java学习路线-39:网络编程TCP、UDP数据传输
Java学习路线-39:网络编程TCP、UDP数据传输
103 0
|
网络协议 Java API
【Java 网络编程】Socket TCP UDP 联系
【Java 网络编程】Socket TCP UDP 联系
128 0