多个客户端使用Socket通过一个服务器进行交互的小例子

Client:

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

public class ChatClient extends Frame {
    private static final long serialVersionUID = 1L;
    private Socket socket;// 声明socket对象
    private TextArea textArea = new TextArea();// 实例化文本域
    private TextField textField = new TextField();// 实例化文本框
    private DataOutputStream dos;// 输出字节流
    private DataInputStream dis;// 输入字节流
    private boolean isConnected;// 标记位,代表是否已经连接上
    Thread thread = new Thread(new RecvThread());// 实例化接收其他客户端发送的消息线程

    public static void main(String[] args) {
        new ChatClient().launchFrame();
    }

    public void launchFrame() {
        setLocation(400, 300);// 设置位置
        setSize(500, 500);// 设置大小
        add(textArea, BorderLayout.NORTH);
        add(textField, BorderLayout.SOUTH);
        pack();// 组件自适应窗口
        addWindowListener(new WindowAdapter() {// 添加窗口监听器,使用匿名类的方式实现
            @Override
            public void windowClosing(WindowEvent e) {
                disConnect();// 关闭连接
                System.exit(0);// 退出
            }
        });
        textField.addActionListener(new TFListener());// 为文本框注册监听事件
        setVisible(true);
        connect();
        thread.start();// 启动线程
    }

    public void connect() {
        try {
            socket = new Socket("127.0.0.1", 64444);
            dos = new DataOutputStream(socket.getOutputStream());
            dis = new DataInputStream(socket.getInputStream());
            isConnected = socket.isConnected();
            System.out.print("LocalAddress->" + socket.getLocalAddress() + ",LocalPort" + socket.getLocalPort());
            System.out.println("succeed connected!");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // TextField的监听器类
    private class TFListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String content = textField.getText().trim();
            String text = textArea.getText();
            if (!"".equals(text))
                text += "\n";
            text += content;// 将内容重新拼接,主要是取出之前的内容,添加textField中的内容,然后重新显示
            textArea.setText(text);
            textField.setText("");// 将textField文本框置空
            try {
                dos.writeUTF(content);// 向服务器端输出信息
                dos.flush();// 刷新缓冲区
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    public void disConnect() {
        try {
            if (dos != null)
                dos.close();
            if (socket != null)
                socket.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }

    private class RecvThread implements Runnable {
        public void run() {
            try {
                while (isConnected) {
                    String str = dis.readUTF();
                    textArea.setText(textArea.getText() + str + "\n");
                }
            } catch (SocketException e) {
                System.out.println("Good bye!" + e.getMessage());
            } catch (EOFException e) {
                System.out.println("Good bye - bye!" + e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }

        }

    }
}

Server:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;

public class ChatServer {
    static ServerSocket serverSocket;
    boolean isStarted = false;// 标志是否启动
    List<Client> clients = new ArrayList<ChatServer.Client>();

    public static void main(String[] args) {
        new ChatServer().start();
    }

    public void start() {
        try {
            serverSocket = new ServerSocket(64444);// 在固定的端口上进行监听
            isStarted = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            while (isStarted) {
                Socket s = serverSocket.accept();// 接受连接请求
                SocketAddress remoteSocketAddress = s.getRemoteSocketAddress();
                System.out.println(remoteSocketAddress.toString());
                System.out.println("a client connected!");
                Client c = new Client(s);// 启动一个线程
                new Thread(c).start();
                clients.add(c);// 加入客户端集合,以便将消息群发给每一个客户端
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (serverSocket != null)
                    serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    class Client implements Runnable {
        private Socket socket;
        private boolean connected = false;
        private DataInputStream dataInputStream;
        private DataOutputStream dataOutputStream;

        public Client(Socket s) {
            this.socket = s;
            try {
                dataInputStream = new DataInputStream(socket.getInputStream());
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                connected = socket.isConnected();
                System.out.println("connected = " + connected);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            String content = null;
            try {
                Client client = null;
                while (connected) {
                    try {
                        content = dataInputStream.readUTF();
                        System.out.println(content);
                        System.out.println("clients.size()=>" + clients.size());
                        for (int i = 0; i < clients.size(); i++) {
                            client = clients.get(i);
                            // 分别向每一个客户端发消息
                            if (client != this)
                                client.dataOutputStream.writeUTF(content);
                        }
                    } catch (EOFException e) {
                        clients.remove(client);// 将客户端移出集合
                        System.out.println(e.getMessage());
                        System.out.println("Client closed!");
                    }
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                try {
                    if (dataInputStream != null)
                        dataInputStream.close();
                    if (dataOutputStream != null) {
                        dataOutputStream.close();
                    }
                    if (socket != null)
                        socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
时间: 2024-10-13 16:18:19

多个客户端使用Socket通过一个服务器进行交互的小例子的相关文章

Java基础知识强化之网络编程笔记14:TCP之多个客户端上传到一个服务器的思考(多线程改进)

1. 多个客户端上传到一个服务器的思考 通过while循环可以改进一个服务器接收多个客户端. 但是这个是有问题的.如果是这种情况,假设我还有张三,李四,王五这三个人分别执行客户端  张三:好好学习.avi(100M) 256k  李四:天天向上.mp3(3M)   1M  王五:ILoveJava.txt(1k) 100M 这要等张三传完了,再去传李四…… 2. 使用多线程改进: (1)线程类UserThread: 1 package cn.itcast_15; 2 3 import java.

[socket编程] 一个服务器与多个客户端之间通信

转自:http://blog.csdn.net/neicole/article/details/7539444 并加以改进 Server程序: 1 // OneServerMain.cpp 2 3 #include <iostream> 4 #include <cstdio> 5 #include <string> 6 #include <cstring> 7 #include <vector> 8 #include <iterator&g

Android 客户端Socket 与 Java服务端ServerSocket 简单小例子

新建一个Java项目 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public

IOS-一个自定义进度条的小例子

//  processDIY.m #import "processDIY.h" static const CGFloat kBorderWidth = 2.0f; @interface THProgressLayer : CAReplicatorLayer @property (nonatomic, strong) UIColor* progressTintColor; @property (nonatomic, strong) UIColor* borderTintColor; @p

C#使用Socket实现一个socket服务器与多个socket客户端通信

在分布式调度系统中,如果要实现调度服务器与多台计算节点服务器之间通信,采用socket来实现是一种实现方式,当然我们也可以通过数据存储任务,子节点来完成任务,但是往往使用数据作为任务存储都需要定制开发,要维护数据库中任务记录状态等等.开发的东西还是有点多,而且还不够灵活.因此,我个人是比较偏向于使用socket来实现任务的调度工作.原因:使用socket实现调度比较灵活,而且扩展性都比较好. 实现思路:调度服务器要实现调度工作,它必须与所有计算节点之间建立连接.而且他需要知道每台计算节点的任务状

Socket编程——怎么实现一个服务器多个客户端之间的连接

  1 package coreBookSocket; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 /* 8 * 这个方法的主要目地是为了用多线程的方法实现网络编程,让多个客户端可以同时连接到一个服务器 9 *1:准备工作和单个客户端编程类似,先建立服务器端的套接字,同时让客户端那边调用accept()方法来接受服务器端的信息 10 *2:这里面定一个w

10、使用TCP协议完成一个客户端一个服务器。客户端从键盘输入读取一个字符串,发送到服务器。 服务器接收客户端发送的字符串,反转之后发回客户端。客户端接收并打印。

/**10.使用TCP协议完成一个客户端一个服务器.客户端从键盘输入读取一个字符串,发送到服务器. 服务器接收客户端发送的字符串,反转之后发回客户端.客户端接收并打印. * 客户端*/ import java.io.*; import java.net.*; public class Test10_Client { public static void main(String[] args) throws Exception { Socket s = new Socket("192.168.0.

Socket 初识 用Socket建立一个简易Web服务器

摘自<Asp.Net 本质论>作者:郝冠军 //在.Net中.system.Net命名空间提供了网络编程的大多数数据据类型以及常用操作,其中常用的类型如下:/*IPAddress 类表示一个IP地址* IPEndPoint类用来表示一个IP地址和一个端口号的组合,成为网络的端点.* System.Net.Sockets命名空间中提供了基于Socked编程的数据类型.* Socket类封装了Socked的操作.* 常见的操作:* Listen:设置基于连接通信的Socket进入监听状态,并设置等

Android客户端通过Socket连接服务器

Android客户端通过Socket连接服务器. Android互联网项目中,绝大部分都有连接远程服务器的需求,连接的方式有多种,可以是TCP的方式,当然也可以通过Socket的方式. 相对于TCP的方式,Socket的方式略显的较为原始,对于客户端来说,复杂度反而比TCP的方式还要高一些,毕竟TCP的连接有现成的框架可以使用, 比如Spring等. 而使用socket方式这些工作完全需要客户端来做,也增加了客户端的工作量,不过凡事有利弊,通过socket的方式,流量上 相对于TCP等的方式更加