java实现基于Tcp的socket聊天程序

对于步入编程行业不深的初学者或是已经有所领会的人来说,当学习一项新的技术的时候,非常渴望有一个附上注释完整的Demo。本人深有体会,网上的例子多到是很多,但是很杂不完整,写代码这种东西来不得半点马虎,要是错了一点,那也是运行不了的。这对于初学者来说更加的头疼,因为他根本不知道错在哪里,盲目的改只能错上加错。最后不得不去找找看看有没有能够直接运行的例子再加以模仿。

下面是博主在学习Java的socket时写的一个完整的例子,并且带上了完整的注释。它是一个简单的聊天程序,但是它可以设置任意多用户同时登录,然后相互两两交流。博主仅仅在自己电脑上实现同时登录,然后两两相互交流。

程序的大体思路是这样的:

①该用户作为服务端也就是被请求连接端和主动请求连接其他端时不一样的,其次有可能被其他的用户连接很多次,那么你作为服务端,就会有很多连接,同样的道理,你作为客户端也会有很多的连接。为了程序更加通俗易懂,博主写的时候,设置了很多容器,将不一样的东西分开放置。做到解耦合,不然到后面自己都分不清了。

②你可以一次写两个类,client1,client2,,client1先作为服务端,client2作为客户端,客户端去连接服务端,从而实现client1的服务端功能和client2的客户端功能。每次实现一个功能就先将服务端和客户端的功能整合一下,互换角色,看是否存在错误。

③在实现了两个用户的情况下再去写第三个类client3,代码就是复制粘贴。当然你也可以直接创建一个client3的类,然后直接在类的main方法中改了端口号,和用户名就行。第三个实现后,第四个第五个也就实了。

下面是具体的代码:

package jack;

import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.format.TextStyle;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.plaf.basic.BasicTabbedPaneUI.TabbedPaneLayout;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT;

import org.omg.CORBA.PRIVATE_MEMBER;
/**
 * 被请求连接时称为服务器;主动连接对方时称为客户端。
 * @author Administrator
 *
 */
public class Client4 extends JFrame implements ActionListener{

 private static int sign = 0;    //用来记录选项卡的标签,0标示第一个。
 private JToolBar toolBar1,toolBar2;
 private JLabel waitPortLabel,hostLabel,portLabel;
 private JTextField waitPortTF,hostTF,portTF,sendTF;
 private JTabbedPane tab;
 private JButton sendB,leaveB,deleteB,connB;
 private ArrayList<ChatThread> serverThreads; //存放服务器线程的容器。即存放被请求连接时所创建的线程的容器。
 private ArrayList<ChatThread> clientThreads; //存放客户端线程的容器。即存放主动连接对方时所创建的线程的容器。
 private ArrayList<ServerSocket> servers;  //服务对象的容器。
 private ArrayList<MyJTextArea> serverTextAreas; //作为服务器时,存放所创建的对话记录显示区域的容器。
 private ArrayList<MyJTextArea> clientTextAreas; //作为客户端时,岑芳所创建的对话记录显示区域的容器。
 private ArrayList<Socket> serverSockets;  //存放被请求连接时所创建的socket的容器。
 private ArrayList<Socket> clientSockets; //存放主动请求连接时所创立的socket的容器。
 private ArrayList<PrintWriter> serverPWriters;  //存放服务端输出流对象的容器。
 private ArrayList<BufferedReader> serverBReaders; //存放服务端输入流对象的容器。
 private ArrayList<PrintWriter> clientPWriters;  //存放客户端输出流对象的容器。
 private ArrayList<BufferedReader> clientBReaders; //存放客户端输入流对象的容器。
 private ArrayList<Integer> ports;  //存放作为服务器时已连接的端口。
 private int port = 2041; //指定自己开放的第一个端口号,方便其他人连接。
 private String name;     //储存自己的名称。

 public Client4(String name) throws IOException{
 super(name);
 this.name = name;
 toolBar1 = new JToolBar();
 toolBar2 = new JToolBar();
 waitPortLabel = new JLabel("等待端口");
 hostLabel = new JLabel("主机");
 portLabel = new JLabel("端口");
 waitPortTF = new JTextField("2041");
 hostTF = new JTextField("127.0.0.1");
 portTF = new JTextField(5);
 sendTF = new JTextField();
 tab = new JTabbedPane();
 sendB = new JButton("发送");
 leaveB = new JButton("离线");
 deleteB = new JButton("删除页");
 connB = new JButton("连接端口");

 servers = new ArrayList<ServerSocket>();
 serverTextAreas = new ArrayList<MyJTextArea>();
 clientTextAreas = new ArrayList<MyJTextArea>();
 serverSockets = new ArrayList<Socket>();
 clientSockets = new ArrayList<Socket>();
 serverPWriters = new ArrayList<PrintWriter>();
 serverBReaders = new ArrayList<BufferedReader>();
 clientPWriters = new ArrayList<PrintWriter>();
 clientBReaders = new ArrayList<BufferedReader>();
 serverThreads = new ArrayList<ChatThread>();
 clientThreads = new ArrayList<ChatThread>();
 ports = new ArrayList<Integer>();

 toolBar1.add(waitPortLabel);
 toolBar1.add(waitPortTF);
 toolBar1.add(hostLabel);
 toolBar1.add(hostTF);
 toolBar1.add(portLabel);
 toolBar1.add(portTF);
 toolBar1.add(connB);

 toolBar2.add(sendTF);
 toolBar2.add(sendB);
 toolBar2.add(leaveB);
 toolBar2.add(deleteB);

 waitPortTF.setEnabled(false);   //设置等待的textfield不可以编辑。
 hostTF.setEnabled(false); //设置连接的ip地址不可编辑,当然这里可以更改成其他电脑的ip地址。
 this.getContentPane().add(toolBar1, "North"); //添加工具栏到最上方。
 this.getContentPane().add(tab,"Center"); //添加选项卡窗格。
 this.getContentPane().add(toolBar2,"South"); //添加工具栏到下方。

 this.setBounds(200, 200, 350, 300);
 this.setVisible(true);
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 sendB.addActionListener(this);
 leaveB.addActionListener(this);
 deleteB.addActionListener(this);
 connB.addActionListener(this);

 //主线程进入之后 在server.accept()阻塞等待客户端来连接。
 while(true){
 ServerSocket server = new ServerSocket(port); //作为服务器,开发自己供连接的端口。
 servers.add(server);
 Socket serverSocket = server.accept();  //等待对方连接。
 serverSockets.add(serverSocket);
 ports.add(port);   //将已连接的端口加入容器。
 PrintWriter serverPWriter = new PrintWriter(serverSocket.getOutputStream(),true);//初始化输出流对象。
 serverPWriters.add(serverPWriter);
 BufferedReader serverBReader = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));//初始化输入流对象。
 serverBReaders.add(serverBReader);
 serverPWriter.println("连接"+name+"成功");  //将连接成功的消息发送给请求方,提醒对方连接成功。
 serverPWriter.println(name);  //将自己的名称发送给对方,方便对方设置选项卡的名称。
 String content = serverBReader.readLine();  //此时对方也发送了上面两条消息过来。读入对方发送过来的提醒消息。
 String name2 = serverBReader.readLine(); //读取对方的名称。方便后面设置选项卡的名称。
 System.out.println(content);
 System.out.println(name2);
 MyJTextArea serverTextArea = new MyJTextArea(sign);
 sign++;      //new了一个textArea后,sign自动增加1,好和选项卡对应,
       //知道这个选项卡加到哪个容器了,是服务器的还是客户端的。
 serverTextAreas.add(serverTextArea);
 this.tab.addTab(name2,new JScrollPane(serverTextArea));//在选项卡窗格中添加一个选项卡。
 serverTextArea.setEditable(false); //设置对话记录显示区域不可编辑。
 serverTextArea.setLineWrap(true); //设置对话记录显示区域自动换行。
 serverTextArea.append(content+"\n"); //在对话记录区域输出连接成功这条消息。
 ChatThread thread = new ChatThread(); //new了一个线程去执行run方法,用于和对方交流,对方也会开启一个线程来和你交流。
  //这里要开启新线程的原因是main线程经过一轮后会在上面accept方法处阻塞。
 serverThreads.add(thread);
 thread.start();     //启动该线程,方便接收对方发来的消息。
 port++;  //端口号加一,开放下一个供连接的端口。
 waitPortTF.setText(port+"");   //更新显示等待的下个端口。
 }
 }

 private class ChatThread extends Thread {

 private String[] serverContents = new String[10]; //当作为服务端时,用来存放相互发送消息时的一句话。
 private String[] clientContents = new String[10]; //当作为客户端时,用来存放相互发送消息时的一句话。
 private boolean isServerThread = true;  //判断当前在执行run方法的线程是不是服务端线程。

 @Override
 public void run() {

 while(true){
 if(serverThreads.size()>0){ //判断当前的线程是否是服务线程。先判断是否大于0,是为了防止serverThreads
 for(int i=0;i<serverThreads.size();i++){ //报数组越界。
 if(Thread.currentThread() == serverThreads.get(i)){ //拿当前线程和服务端容器里的线程去比,看是否是服务端的线程。
 isServerThread = true;
 }
 }
 }

 if(clientThreads.size()>0){   //判断当前的线程是否是客户线程。 先判断是否大于0,是为了防止clientThreads
 for(int i=0;i<clientThreads.size();i++){ //报数组越界。
 if(Thread.currentThread() == clientThreads.get(i)){ //拿当前线程和客户端容器里的线程去比,看是否是客户端的线程。
 isServerThread = false;
 }
 }
 }

 if(isServerThread){   //如果是服务端的线程,将readline方法接受到的值赋给相应的content。
 for(int i=0;i<serverThreads.size();i++){
 if(Thread.currentThread() == serverThreads.get(i)){ //判断具体是服务端里的那条线程。
 try {
 serverContents[i] = serverBReaders.get(i).readLine();//将对方发送过来的消息赋值给这条线程的接受消息字符串。
 } catch (IOException e) {
 e.printStackTrace();
 return;  //出现异常时直接退出方法。
 }
 if(serverContents[i]==null){  //在自己点击离线按钮时,serverContents[i]为null,
 return;  //因此在这里进行处理,避免后面报错。
 }
 if(serverContents[i].equals("关闭")){ //接收到对方因点击离开按钮而发出的消息“离开”,关闭自己的连接。
 sendTF.setText("已断开连接");
 serverPWriters.get(i).close();
 try {
  serverBReaders.get(i).close();
  serverSockets.get(i).close();
 } catch (IOException e) {
  e.printStackTrace();
 }
 return;    //关闭完后退出。
 }
 serverTextAreas.get(i).append(serverContents[i]+"\n");//将接受到的消息显示在自己的对话记录区域。
 break;
 }

 }
 }else{    //如果是客户线程,将readline方法接受到的值赋给相应的content。
 for(int i=0;i<clientThreads.size();i++){
 if(Thread.currentThread() == clientThreads.get(i)){ //判断具体是客户端中的哪一条线程。
 try {
 clientContents[i] = clientBReaders.get(i).readLine();//拿到对方发送过来的消息并保存给自己的字符串。
 } catch (IOException e) {
 e.printStackTrace();
 }
 if(clientContents[i] == null){ //当自己点击离线按钮时,clientContents[i]会为null,
 return; //为了防止下面报错,在这里进行处理。
 }
 if(clientContents[i].equals("关闭")){ //接收到对方因点击离线按钮而发出的消息“关闭”,而关闭自己的连接。
 sendTF.setText("已断开连接");
 clientPWriters.get(i).close();
 try {
  clientBReaders.get(i).close();
  clientSockets.get(i).close();
 } catch (IOException e) {
  e.printStackTrace();
 }
 return;
 }
 clientTextAreas.get(i).append(clientContents[i]+"\n");//作为客户端时,将接受到的消息显示在对话记录显示区域。
 break;
 }
 }
 }
 }
 }
 }

 @Override
 public void actionPerformed(ActionEvent e) {
 switch(e.getActionCommand()){
 case "连接端口":      //如果是连接端口,则执行以下操作。
 try {
 Socket clientSocket = new Socket(hostTF.getText(),Integer.parseInt(portTF.getText()));//拿到工具栏一中填的端口号并生成socket去连接对方。
 clientSockets.add(clientSocket);
 PrintWriter clientPWriter = new PrintWriter(clientSocket.getOutputStream(),true);//初始化输出流对象。
 clientPWriters.add(clientPWriter);
 BufferedReader clientBReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));//初始化输入流对象。
 clientBReaders.add(clientBReader);
 clientPWriter.println("连接"+name+"成功");  //将连接成功的消息发送给对方,提醒对方连接成功。
 clientPWriter.println(name); //将自己的名称发送给对方,方便对方设置选项卡的名称。
 System.out.println(11111111);
 String content = clientBReader.readLine(); //读入对方发送过来的提醒消息。对方已执行了上面两条语句,发送了对应的消息。
 System.out.println(22222222);
 String name2 = clientBReader.readLine(); //读取对方的名称。
 System.out.println(content);
 System.out.println(name2);
 MyJTextArea clientTextArea = new MyJTextArea(sign);
 sign++;  //配和选项卡的index,记录每个选项卡加到那个容器里去了,是服务器的容器还是客户端的容器。
 clientTextAreas.add(clientTextArea);
 this.tab.addTab(name2,new JScrollPane(clientTextArea)); //在选项卡窗格中添加一个选项卡。
 clientTextArea.setEditable(false);  //设置对话记录区域不可编辑。
 clientTextArea.setLineWrap(true);  //设置对话记录区域自动换行。
 clientTextArea.append(content+"\n"); //在对话记录区域显示连接成功这条消息。
 ChatThread clientThread = new ChatThread();
 clientThreads.add(clientThread);
 clientThread.start();    //启动该线程,方便和对方相互发送消息,因为主线程已经在上面accept()处阻塞。
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 break;
 case "发送":
 if(serverTextAreas.size()>0){    //如果是被请求连接时而创建的选项卡要发送消息。即服务端。
 for(int i=0;i<serverTextAreas.size();i++){
 if(tab.getSelectedIndex() == serverTextAreas.get(i).getSign()){ //通过获取当前选项卡的index去和jtextArea的sign比,因为他们的index和sign是匹配的,
 String sendContent = sendTF.getText(); //从而确定它是服务端的哪条线程,该用那对输入输出流进行发送和接受消息。
 if(serverSockets.get(i).isClosed()){ //如果已断开连接,则直接返回。
 sendTF.setText("已断开连接");
 return;
 }
 if(sendContent.equals("")){  //如果发送的内容为空则直接接结束。
 sendTF.setText("请输入内容");
 return;
 }else{
 serverPWriters.get(i).println(name+": "+sendContent); //将发送消息框中的消息发送出去,并在前面加上自己的姓名。
 serverTextAreas.get(i).append("我: "+sendContent+"\n");//在自己的对话记录区域加上这句话。
 sendTF.setText("");     //将发送消息框中的数据清空。
 return;
 }

 }
 }
 }

 if(clientTextAreas.size()>0){    //如果是客户端。
 for(int i=0;i<clientTextAreas.size();i++){
 if(tab.getSelectedIndex() == clientTextAreas.get(i).getSign()){ //通过获取当前选项卡的index去和jtextArea的sign比,因为他们的index和sign是匹配的,
 String sendContent = sendTF.getText();   //从而确定它是客户端的哪条线程,该用那对输入输出流进行发送和接受消息。
 if(clientSockets.get(i).isClosed()){ //如果连接已断开则直接返回。
 sendTF.setText("已断开连接");
 return;
 }
 if(sendContent.equals("")){  //如果发送的内容为空则直接接结束。
 sendTF.setText("请输入内容");
 return;
 }else{
 clientPWriters.get(i).println(name+": "+sendContent); //将发送消息框中的消息发送出去,并在前面加上自己的姓名。
 clientTextAreas.get(i).append("我: "+sendContent+"\n"); //在自己的对话记录区域加上这句话
 sendTF.setText("");     //将发送消息框中的数据清空。
 return;
 }
 }
 }
 }

 break;
 case "离开":
 if(serverTextAreas.size()>0){      //如果是服务端。
 for(int i=0;i<serverTextAreas.size();i++){
 if(tab.getSelectedIndex() == serverTextAreas.get(i).getSign()){ //更前面一样的道理,判断是服务端的那个选项卡需要闭关。
 serverPWriters.get(i).println("关闭");   //发送关闭消息,提醒对方也要关闭该socket连接。
 sendTF.setText("已断开连接");
 serverPWriters.get(i).close();
 try {
 serverBReaders.get(i).close();
 serverSockets.get(i).close();
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 break;
 }
 }
 }

 if(clientTextAreas.size()>0){      //如果是客户端。
 for(int i=0;i<clientTextAreas.size();i++){
 if(tab.getSelectedIndex() == clientTextAreas.get(i).getSign()){ //更前面一样的道理,判断是客户端的那个选项卡需要闭关。
 clientPWriters.get(i).println("关闭");   //发送关闭消息,提醒对方也要关闭该socket连接。
 sendTF.setText("已断开连接");
 clientPWriters.get(i).close();
 try {
 clientBReaders.get(i).close();
 clientSockets.get(i).close();
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 break;
 }
 }
 }
 break;
 case "删除页":
 if(serverTextAreas.size()>0){ //为了防止下面的serverTextAreas数组越界。
 for(int i=0;i<serverTextAreas.size();i++){
 if(tab.getSelectedIndex() == serverTextAreas.get(i).getSign()){ //跟上面一样的道理,判断当前选项卡是属于服务端还是客户端。
 if(serverSockets.get(i).isClosed()){ //先判断是否断开连接,否则不允许关闭。
 tab.remove(i);  //删除当前选项卡。
 }else{
 sendTF.setText("请先关闭当前的连接");
 return;
 }
 }
 }
 }
 if(clientTextAreas.size()>0){ //为了防止下面的serverTextAreas数组越界。
 for(int i=0;i<clientTextAreas.size();i++){
 if(tab.getSelectedIndex() == clientTextAreas.get(i).getSign()){ //跟上面一样的道理,判断当前选项卡是属于服务端还是客户端。
 if(clientSockets.get(i).isClosed()){ //先判断是否断开连接,否则不允许关闭。
 tab.remove(i);   //删除当前选项卡。
 }else{
 sendTF.setText("请先关闭当前的连接");
 return;
 }
 }
 }
 }
 break;
 default:
 break;
 }
 }

 public static void main(String[] args) throws IOException{
 new Client4("喜洋洋");
 }
}

效果图:

源码下载:Java基于Tcp的socket聊天程序

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现Socket通信之单线程服务

    前言 使用基于TCP 协议的双向通信时,网络中的两个应用程序之间必须首先建立一个连接,这两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口:HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力. Socket的英文原义是"孔"或

  • 详解Java基础篇--面向对象1(构造方法,static、this关键字)

    面向对象,面向过程的区别.拿下五子棋来说: 面向过程分析: 开始游戏 黑棋先走 绘制画面 判断输赢 轮到白棋 绘制画面 判断输赢 返回步骤2 输出结果 面向对象分析: 黑白双方,双方行为是一模一样的 棋盘系统,负责绘制画面 规则系统,判断犯规.输赢 传统的面向过程编程是思考问题的解决步骤,这种思维方式适用于问题规模较小时.可是当问题规模大,要求程序有更好的可扩展性,能更快速地查错时面向对象设计思想就能体现出其优势.面向对象更接近人类地自然思维方式,将现实世界中的事物抽象为对象和对象的方法. 面向

  • Java中Connection timed out和Connection refused的区别讲解

    前言:这两个异常报出的时候,说明客户端没法正常连接到服务端,但是两者还是有区别的. 1:Connection timed out 在实际开发中经常会碰到Connection timed out的问题 java.net.ConnectException: Connection timed out (Connection timed out) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPl

  • 基于Java语言实现Socket通信的实例

    基于Java语言实现Socket通信 由于近日项目需求,需要在服务器中增加Socket通信的功能,接收硬件设备发送的心跳包和相关数据,因此又重新对Java的网络编程进行了复习,根据项目的实际情况做了简化的编程,实现了简单的通信过程. 1. Socket通信原理 源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字.其用于标识客户端请求的服务器和服务. 以下是通过Socket套接字实现客户端与服务器端通信的示意图: 在实际应用中,客户端会通过访问服务器的IP和PORT连接到服务器端,这

  • Java的外部类为什么不能使用private和protected进行修饰的讲解

    Java的外部类为什么不能使用private和protected进行修饰 对于这个问题,一直没有仔细思考,今天整理一下: 对于顶级类(外部类)来说,只有两种修饰符:public和默认(default).因为外部类的上一单元是包,所以外部类只有两个作用域:同包,任何位置.因此,只需要两种控制权限:包控制权限和公开访问权限,也就对应两种控制修饰符:public和默认(default). 如果类使用了private修饰符,说明是个内部类.内部类的上一级是外部类,那么对应的有四种访问控制修饰符:本类(p

  • Java开发实现的Socket双向通信功能示例

    本文实例讲述了Java开发实现的Socket双向通信功能.分享给大家供大家参考,具体如下: 服务端 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java

  • Java基于socket实现的客户端和服务端通信功能完整实例

    本文实例讲述了Java基于socket实现的客户端和服务端通信功能.分享给大家供大家参考,具体如下: 以下代码参考马士兵的聊天项目,先运行ChatServer.java实现端口监听,然后再运行ChatClient.java 客户端实例 ChatClient.java package socketDemo; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Ch

  • Java网络通信中ServerSocket的设计优化方案

    前言:在java的网络通信中,两个不同节点的主机想要进行通信则可以通过建立Socket对象(相当于客户端主机,向服务端请求发送信息)和ServerSocket对象(相当于服务端主机,接收客户端的连接请求并回复信息)实现. 1:创建一个Socket对象 Socket socket = new Socket("IP",port); 指定将要连接的服务端的ip地址和端口号来创建一个Socket对象,在创建结束之后便可对其进行输出.输入操作. 2:创建一个ServerSocket对象 Serv

  • java+jdbc+mysql+socket搭建局域网聊天室

    本文实现思路:利用UDP协议进行局域网信息传输,建立点对点的聊天网络,每个端用户有自己的一个mysql数据库,所以需要获取其数据库用户名和密码,然后通过该数据库内容发送信息,接收消息则没有限制, 步骤: 建立数据表存储主机ip,接收信息端口port,nickname 向所有用户发送信息 接收信息 小部件(添加好友,删除好友) 一.建立数据表存储主机ip,接收信息端口port,nickname 在mysql数据库里建立chatusr数据表,表的格式为: 检测表是否存在和建立数据表的代码如下: vo

  • java使用socket实现一个多线程web服务器的方法

    除了服务器类,还包括请求类和响应类 请求类:获取客户的HTTP请求,分析客户所需要的文件 响应类:获得用户请求后将用户需要的文件读出,添加上HTTP应答头.发送给客户端. 服务器处理类 package com.lp.app.webserver; import java.io.*; import java.net.*; //使用Socket创建一个WEB服务器,本程序是多线程系统以提高反应速度. class WebServer { public static String WEBROOT = "&

随机推荐