java客户端与服务端建立连接 线程 ServerSocket

原创 2017年06月25日 09:19:20
package chat;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/*
 * 聊天客户端
 */
public class Client {
    /*
     * java.net.Scoket 套接字
     * 封装了TCP通讯,使用它可以通过网络连接到服务端并进行数据交换(通讯)
     */
    private Socket socket;
    /*
     * 构造方法
     * 用于初始化客户端
     */
    public Client() throws Exception{
        try {
            /*
             * 实例化Scoket的过程就是与远端计算机建立连接的过程
             * 实际上建立连接是客户端应用程序与服务端应用程序建立的连接
             * 那么这里实例化Scoket需要传入两个参数
             * 1:服务器端计算机的IP地址(用于在网络中找到服务器端电脑)
             * 2:端口号(通过端口号可以找到运行在服务器中的服务端应用程序)
             */
            System.out.println("正在连接服务器。。。");
            socket = new Socket("localhost",8080);
            System.out.println("已建立连接!");
        } catch (Exception e) {
            throw e;
        }
    }
    /*
     * 客户端的启动方法
     */
    public void start(){
        try {
            /*
             * Socket 提供方法:
             * OutputStream getOutputStream
             * 该方法可以获取一个字节输出流,通过该流写出的数据都会发送给远端计算机
             * 对于客户而言,远端就是服务端
             */

            Scanner scan = new Scanner(System.in);
            //客户端输出
            OutputStream out = socket.getOutputStream();
            //转换指定字符集
            OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
            //缓冲 字符输出流
            PrintWriter pw = new PrintWriter(osw,true);

            //启动读取服务端发送过来消息的线程
            ServerHandler handler = new ServerHandler();
            Thread t = new Thread(handler);
            t.start();


            System.out.println("开始聊天");
            String message = null;
            while(true){
                message = scan.nextLine();
                pw.println(message);
//              //读取服务端发送回来的内容
//              message = br.readLine() ;
//              System.out.println(message);
            }

        } catch (Exception e) {
            e.printStackTrace();
            }
    }
    /*
     * 该线程专门用来接收服务端发送过来的消息并输出到控制台
     */
    private class ServerHandler implements Runnable{
        public void run(){
            try {
                //客户端输入
                InputStream in  = socket.getInputStream();
                //字符
                InputStreamReader isr = new InputStreamReader(in,"utf-8");
                //字符
                BufferedReader br = new BufferedReader(isr);
                String message = null;
                while((message = br.readLine())!= null){
                    System.out.println(message);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            Client client = new Client();
            client.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package chat;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/*
 * 服务器端
 * 
 */
public class Server {
    /*
     * java.net.ServerSocket; 运行在服务端的ServerScoket主要职责:
     * 1:向OS申请服务端口(客户端就是同过这个端口与服务端建立连接的) 
     * 2:监听服务端口并建立与客户端的连接
     */
    private ServerSocket server;
    //存放所有客户端的输出流,用于广播消息
    private List<PrintWriter> allOut;
    /*
     * 服务端构造方法,用来初始化服务端
     */
    public Server() throws Exception {
        try {
            /*
             * 初始化ServerSocket的同时向系统申请服务器端口, 若该端口已经被其他程序占用则会抛出异常
             */
            server = new ServerSocket(8080);
            allOut = new ArrayList<PrintWriter>();

        } catch (Exception e) {
            // 将来在这里可以记录日志
            // 异常若不应当在这里处理,继续抛出
            throw e;
        }

    }

    /*
     * 服务端开始工作的方法
     */
    public void start() {

        try {
            /*
             * ServerSocket提供方法: Socket accept()
             * 该方法是一个阻塞方法,作用是监听服务端口,等待客户端的连接一旦一个客户端请求连接
             * 那么accept方法会解除阻塞,并返回一个Socket实例,服务器就可以通过这个Socket 
             * 实例与客户端交互
             */
            while(true){
            System.out.println("等待一个客户端连接。。");
            Socket socket = server.accept();
            System.out.println("一个客户端连接了");

            //启动一个线程来负责与该客户端交互
            ClientHandler handler = new ClientHandler(socket);
            Thread t = new Thread(handler);
            t.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private class ClientHandler implements Runnable {
        /*
         * 当前线程就是通过这个Socket与指定客户端交互的
         * 
         */

        private Socket socket;

        //当前客户端的地址信息
        private String host;


        public ClientHandler(Socket socket) {
            this.socket = socket;
            //获取该客户端地址信息(远端计算机地址信息)
            InetAddress address = socket.getInetAddress();
            host = address.getHostAddress();
        }

        public void run() {
            PrintWriter pw = null;
            try {
                /*
                 * Socket 提供方法: InputStream getInputStream()
                 * 通过这个流读取到的数据就是远端发送过来的数据
                 */
                // 服务端输入
                // 字节
                InputStream in = socket.getInputStream();
                // 字符
                InputStreamReader isr = new InputStreamReader(in, "utf-8");
                // 字符
                BufferedReader br = new BufferedReader(isr);

                // 服务端输出
                OutputStream out = socket.getOutputStream();
                // 转换指定字符集
                OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
                // 缓冲 字符输出流
                pw = new PrintWriter(osw, true);


                //将该客户端的输出流存入共享集合
                synchronized(allOut){//锁集合 保证多个线程不能同时调用
                    allOut.add(pw);
                }
                //广播当前客户端上线
                sendMessage(host+"上线了");

                String message = null;
                while ((message = br.readLine()) != null) {
                    Thread t = Thread.currentThread();
                    System.out.println("客户" +t.getName()+":"+ message);
//                  // 发送回给客户端
//                  pw.println("客户端说:" + message);

                    //遍历集合,发送给所有客户端
                    sendMessage(host+":"+message);

                }

            } catch (Exception e) {
                //e.printStackTrace();
            }finally{


                //处理客户端断开连接后的操作

                //将该客户端的输出流从共享集合中删除
                synchronized(allOut){
                    allOut.remove(pw);

                }
                sendMessage(host+"下线了");

                try{
                    /*
                     * 网络通讯完毕后关闭socket
                     */
                socket.close();
                }catch(Exception e){
                }

            }

        }
    /*
     * 将消息广播给所有客户端
     */
        private void sendMessage(String message){
            synchronized(allOut){
                for(PrintWriter o : allOut){
                    o.println(message);
                }
            }
        }
    }


    public static void main(String[] args) {
        try {
            Server server = new Server();
            server.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Java通信之客户端的创建以及客户端和服务器的简单交互

Java通信之客户端的创建以及客户端和服务器的简单交互 一、客户端的创建 现在所使用的是windows自带telnet客户端,并且只能发送英文,今天我们将自己创建客户端,并让客户端和服务器进行简答...
  • BlueSky_USC
  • BlueSky_USC
  • 2017年01月14日 01:27
  • 3631

一个 Java 的 Socket 服务器和客户端通信的例子

一个 HelloWord 级别的 Java Socket 通信的例子。通讯过程:         先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求。然后运行 Client 端...
  • defonds
  • defonds
  • 2012年09月12日 15:21
  • 138559

Java简单的客户端与服务器的建立与通信

简述: 建立简单的server与client,在利用socket上通信 知识点: 1. java socket 通信 2. java GUI的几个控件 3. 多线程并发 ...
  • anialy
  • anialy
  • 2012年08月26日 00:04
  • 19161

Java Socket实现客户端服务端相互发送文本

Socket是网络编程的接口,它抽象成线程之间的接口。两个线程,不管它的操作系统,不管它的硬件,只要有Socket接口,在同一主机中或者在不同的主机中都能通信。我们见到的大大小小的网络程序大多都是通过...
  • e_one
  • e_one
  • 2016年06月09日 14:39
  • 8074

java 客户端和服务端通信

  • 2016年12月20日 20:44
  • 1003KB
  • 下载

JAVA Socket服务器 判断客户端连接断开

备忘: sendUrgentDatapublic void sendUrgentData(int data) throws IOException在套接字上发...
  • kingdom578
  • kingdom578
  • 2010年11月11日 00:34
  • 1874

用ServerSocket类与Socket类实现客户端与服务端的交互

ServerSocket类,此类实现服务端的套接字,Socket类,此类实现客户端的套接字,而套接字就是两台机器间通信的端点,所以就用ServerSocket类和Socket类实现客户端与服务端的交互...
  • Zero_zzq
  • Zero_zzq
  • 2017年04月09日 22:58
  • 944

java socket客户端和服务端实例

以下代码参考马士兵的聊天项目,先运行ChatServer.java实现端口监听,然后再运行ChatClient.java 客户端实例 ChatClient.java import j...
  • nuli888
  • nuli888
  • 2016年07月11日 23:31
  • 7758

java版qq(客户端和服务器端)

  • 2015年03月10日 19:56
  • 19.64MB
  • 下载

tserversocket判断客户端状态

浅谈socket编程心得做了好一阵的socket通信,觉得网络通信这东西真是不怎么好弄,感觉很多都不在自己的控制当中。尤其对于实时系统来说,如何保证不丢一条数据,如何管理每个客户端的连接真是不那么简单...
  • Jianor
  • Jianor
  • 2006年12月13日 11:18
  • 1547
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java客户端与服务端建立连接 线程 ServerSocket
举报原因:
原因补充:

(最多只允许输入30个字)