java实现tcp服务器(单线程、多线程)、客户端

全栈工程师开发手册 (作者:栾鹏)
java教程全解

java实现tcp服务器(单线程、多线程)、客户端。

服务器端接收客户申请,响应时间戳和用户源字符串。

客户端使用控制台作为输入输出流

tcp服务器端代码

package com.lp.app.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

//tcp服务器,单线程和多线程
public class TCPServer{
	
	public static void main(String[] args) {
		moreserver(1234);
	}

	//读取输入文本,返回响应文本(二级制,对象)
	public static void  server(int port) {
		try {
			//创建一个serversocket
			ServerSocket mysocket=new ServerSocket(port);
			//等待监听是否有客户端连接
			Socket sk = mysocket.accept();
			//接收文本信息
			BufferedReader in =new BufferedReader(new InputStreamReader(sk.getInputStream()));
			String data =in.readLine();
			System.out.println("客户端消息:"+data);
			
//			//接收二进制字节流
//			DataInputStream dis =new DataInputStream(new BufferedInputStream(sk.getInputStream()));
//			byte[] enter =new byte[dis.available()];
//			dis.read(enter);
//			
//			//接收对象信息
//			ObjectInput ois =new ObjectInputStream(new BufferedInputStream(sk.getInputStream()));
//			Object object=ois.readObject();
			
			//输出文本
			PrintWriter out =new PrintWriter(new BufferedWriter(new OutputStreamWriter(sk.getOutputStream())),true);
			out.println(new Date().toString()+":"+data);   //服务器返回时间和客户发送来的消息
			out.close();
			
//			//输出二进制
//			DataOutputStream dos=new DataOutputStream(sk.getOutputStream());
//			byte[] back="luanpeng".getBytes();
//			dos.write(back);
//			
//			//输出对象
//			ObjectOutputStream oos=new ObjectOutputStream(sk.getOutputStream());
//			oos.writeObject(new Date());  //返回一个时间对象
//			oos.close();

		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}
	

	
	//多线程服务器
	public static void moreserver(int port){
		try {
			System.out.println("服务器启动...............");
			ServerSocket server=new ServerSocket(port);
			while(true)
			{
				//阻塞,直到有客户连接
				Socket sk=server.accept();
				//启动服务线程
				new ServerThread(sk).start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}


//使用线程为多个客户端服务
class ServerThread extends Thread
{
	private Socket sk;
	ServerThread(Socket sk)
	{
		this.sk=sk;
	}
	//线程运行实体
	public void run() {
		BufferedReader in=null;
		PrintWriter out=null;
		try {
			InputStreamReader isr;
			isr=new InputStreamReader(sk.getInputStream());
			in=new BufferedReader(isr);
			out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(sk.getOutputStream())),true);
			while(true)
			{
				//接收来自客户端的请求,根据不同的命令返回不同的信息
				String cmd=in.readLine();
				System.out.println(cmd);
				if (cmd==null) {
					break;
				}
				out.println(new Date().toString()+":"+cmd);   //服务器返回时间和客户发送来的消息
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			try {
				if (in!=null) {
					in.close();
				}
				if (out!=null) {
					out.close();
				}
				if (sk!=null) {
					sk.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
}


tcp客户端代码

package com.lp.app.net;

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

//客户端
public class TCPClient {
	
	public static void main(String [] args) throws IOException {
		connect("192.168.8.102", 1234);
	}
		
	//远程连接
	public static void connect(String host,int port){
		try {
			System.out.println("客户端启动...............");
			Socket sock = new Socket(host, port);
			// 创建一个写线程
			new TelnetWriter(sock.getOutputStream()).start();
			// 创建一个读线程
			new TelnetReader(sock.getInputStream()).start();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

//从控制台读取用户输入命令   线程类
class TelnetWriter extends Thread {
	private PrintStream out;

	public TelnetWriter(OutputStream out) {
		this.out = new PrintStream(out);
	}
	public void run() {
		try {
			// 包装控制台输入流
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			// 反复将控制台输入写到Telnet服务程序
			while (true)  
				out.println(in.readLine());
		} catch (IOException exc) {
			exc.printStackTrace();
		}
	}
}

//将响应数据打印到控制台   线程类
class TelnetReader extends Thread {
	private InputStreamReader in;

	public TelnetReader(InputStream in) {
		this.in = new InputStreamReader(in);
	}
	public void run() {
		try {
			// 反复将Telnet服务程序的反馈信息显示在控制台屏幕上
			while (true) {
				// 从Telnet服务程序读取数据
				int b = in.read();
				if (b == -1)  
					System.exit(0);
				// 将数据显示在控制台屏幕上
				System.out.print((char) b);
			}
		} catch (IOException exc) {
			exc.printStackTrace();
		}
	}
}


  • 11
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
实现TCP多线程传输文件可以分为以下步骤: 1. 创建一个ServerSocket,监听客户端的连接请求。 2. 当有客户端连接时,创建一个新的线程来处理客户端的请求。 3. 在新的线程中,创建一个Socket与客户端进行通信。 4. 通过Socket获取输入输出流,进行文件的读写。 5. 将文件分成多个块,每个块单独发送,接收方将块合并成完整文件。 下面是一个示例代码,实现TCP多线程传输文件: ```java import java.io.*; import java.net.*; public class Server { public static void main(String[] args) { try { // 创建ServerSocket,监听客户端的连接请求 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器启动,等待客户端连接..."); while (true) { // 当有客户端连接时,创建一个新的线程来处理客户端的请求 Socket clientSocket = serverSocket.accept(); System.out.println("客户端 " + clientSocket.getInetAddress().getHostAddress() + " 连接成功"); Thread thread = new Thread(new ClientHandler(clientSocket)); thread.start(); } } catch (IOException e) { e.printStackTrace(); } } // 处理客户端请求的线程 static class ClientHandler implements Runnable { private Socket clientSocket; public ClientHandler(Socket clientSocket) { this.clientSocket = clientSocket; } @Override public void run() { try { // 通过Socket获取输入输出流 DataInputStream dis = new DataInputStream(clientSocket.getInputStream()); DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream()); // 读取客户端传来的文件名和大小 String fileName = dis.readUTF(); long fileSize = dis.readLong(); System.out.println("客户端传来的文件名:" + fileName); System.out.println("客户端传来的文件大小:" + fileSize + " 字节"); // 创建文件输出流,将文件写入到服务器端指定目录 FileOutputStream fos = new FileOutputStream("/path/to/save/" + fileName); // 将文件分成多个块,每个块单独发送 byte[] buffer = new byte[1024]; int len; while ((len = dis.read(buffer)) != -1) { fos.write(buffer, 0, len); } // 关闭流 fos.close(); dis.close(); dos.close(); clientSocket.close(); System.out.println("文件接收成功"); } catch (IOException e) { e.printStackTrace(); } } } } ``` 客户端代码如下: ```java import java.io.*; import java.net.*; public class Client { public static void main(String[] args) { try { // 创建Socket,连接服务器 Socket socket = new Socket("localhost", 8888); System.out.println("连接服务器成功"); // 通过Socket获取输入输出流 DataInputStream dis = new DataInputStream(socket.getInputStream()); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); // 读取本地文件,将文件名和大小发送给服务器 File file = new File("/path/to/file"); String fileName = file.getName(); long fileSize = file.length(); dos.writeUTF(fileName); dos.writeLong(fileSize); System.out.println("文件名:" + fileName); System.out.println("文件大小:" + fileSize + " 字节"); // 创建文件输入流,将文件发送给服务器 FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { dos.write(buffer, 0, len); } // 关闭流 fis.close(); dis.close(); dos.close(); socket.close(); System.out.println("文件发送成功"); } catch (IOException e) { e.printStackTrace(); } } } ``` 在这个示例代码中,服务器客户端都是单线程的,每次只能处理一个客户端请求。如果需要支持多个客户端同时连接,可以使用线程池来管理多个线程,每个线程负责处理一个客户端请求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾讯AI架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值