简易命令行界面的C/S聊天室

最近几天复习了下java网络编程socket使用我觉得虽然下面的内容很基础但是如果想要做出个好的东西想要快速掌握以后要学习的先要把基础打牢

如果基础打得好那么将来学习新的知识会很快,其实都是同理的。

如果大神能发挥下,拓展下完善下功能那就更好了,请在下面留下您的想法我会一直维护我的这些文章。

TCP 协议基础

IP协议是Internet的使用的一个关键协议,全称是Internet Protocol,即Internet协议通常简称IP协议通过IP协议,从而使Internet成为一个允许连接不同类型计算机的不同操作系统的网络。如果想要两台计算机通信那么就要使用相同的语言 那么就是用IP协议但是只保证计算机能发送接受分组数据,IP协议负责将消息从一个主机发送到另一个主机,消息在传送过程中被分割成包。但是这样只是解决了他们之间的发送和接收数据但是还不能解决数据分组在数据传输过程中出现的问题。所以就需要使用TCP协议以保证提供可靠并且无差错的通信服务。

TCP协议是面向连接的端对端的协议。这是因为他对两台计算机之间的链接起到了重要的作用建立的链接用于发送和接收数据的虚拟链路

TCP和IP协议的功能虽然不尽相同,也可以分开使用,但是他们是在同一时期作为一个协议来设计的,并且在功能上也是互补的。只有两者结合起来才能保证internet在复杂的环境下正常的运行凡事要连接到internet的计算机都必须同时安装和使用这两个协议因此唱吧这两个协议叫做TCP/IP协议

使用serverSocket创建TCP服务器端

在两个通信实体之间没有建立虚拟链路之前必须先有一个通信实体先做出“主动姿态”主动地接受来自其他实体的连接请求。Java中接收其他的通信实体连接请求的类是ServerSocket,serverSocket用于监听来自socket端的连接,如果没有连接,他将一直处于等待状态,serverSocket包含一个监听来自客户端请求的方法

Socket accept():如果接收到一个客户端的Socket的链接的请求,该方法返回一个与客户端对应的socket否则该方法一直处于等待状态线程也被阻塞

为了创建serversocket对像,提供了如下几个构造器

serverSocket(int port)指定的端口创建一个serverSocket对像该端口应该有一个有效的端口整数

serverSocket(int port,int backlog):增加一个用来改变连接队列长度的参数backlog

当serverSocket使用完毕后,应使用serverSocket的close()方法关闭该serverSocket。在通常情况下

服务器不用改制接受一个客户端的请求,而应该不断地接受来自客户端的所有的请求,所以java程序通常会循环的不断的调用serverSocket的accept()方法

使用socket进行通信

客户端通常可以使用socket的构造器连接到指定的服务器,socket通常可以使用给定的两个构造器连接到相应的主机或者是相应的IP地址的服务器这样就能实现对话

--

加入多线程

前面的Server和Client只是进行了简单的通信操作:服务器端接收到客户端的连接之后,服务器端向客户端输出了一个字符串,而客户但也只是读取服务器端的字符串后就退出了,实际应用中的客户端可能根据需要和服务器端保持长时间通信,即服务器端需要不断的读取客户端数据,并向客户端写入数据;客户端也需要不断的读取服务器端的数据,并向服务器端写入数据。

在使用传统的BufferReader的readLine()方法读取数据时,在该方法成功返回之前,线程被阻塞,程序无法执行。考虑到这个因素,服务器端应该为每个Socket启动一个线程,每个线程负责与一个客户端进行通信

客户端读取服务器端数据的县城同样会被阻塞,所以系统应该单独启动一个线程。该线程专门负责读取服务器端的数据。

现在考虑实现一个命令行的界面的C/S聊天室应用,服务器端应该包含多个线程,每个Socket对应一个线程,该线程负责读取Socket对应输入流的数据。并将读取到的数据向每个Socket输出流发送一次(将一个客户端的数据广播给其他客户端)需要在服务器端使用list保存所有的Socket

服务器端的实现:

<span style="font-size:18px;"><span style="font-size:18px;">package com.example.administrator.openinternet;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created by Administrator on 2015/7/23.
 * 服务器端的程序
 */
public class javaSocket {
    public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());
    public static void main (String [] args) throws IOException {
        ServerSocket ss = new ServerSocket(30000);
        while(true)
        {
            Socket s = ss.accept();
            socketList.add(s);
            new Thread( new ServerThread(s)).start();
        }
    }
}
</span></span>

服务器端的线程类:

<span style="font-size:18px;"><span style="font-size:18px;">package com.example.administrator.openinternet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketException;

/**
 * Created by Administrator on 2015/7/23.
 * 服务器端的线程
 */
public class ServerThread implements Runnable {
    Socket s = null;
    BufferedReader br = null;
    public ServerThread(Socket s){
        this.s = s ;
        try {
            br = new BufferedReader(new InputStreamReader(s.getInputStream()));//创建并读取流
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Starts executing the active part of the class' code. This method is
     * called when a thread is started that has been created with a class which
     * implements {@code Runnable}.
     */
    @Override
    public void run()
    {
        try
        {
            String content = null;
            while ((content = readFromClient())!=null)
            {
                for(Socket s:javaSocket.socketList)
                {
                    PrintStream ps = new PrintStream(s.getOutputStream());
                }
            }

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

    private String readFromClient() {
        try
        {
            return br.readLine();

        }catch (IOException e) {
            e.printStackTrace();
            javaSocket.socketList.remove(s);//移除socketList中的数据三
        }
        return null;
    }
}
</span></span>

客户端实现:

<span style="font-size:18px;">package com.example.administrator.openinternet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

/**
 * Created by Administrator on 2015/7/23.
 * 我的客户端的程序
 */
public class MyClient {
    public static void main(String [] args) throws IOException
    {
        Socket s = new Socket("127.0.0.1",30000);
        new Thread( new ClientThread(s)).start();
        PrintStream ps = new PrintStream(s.getOutputStream());
        String line = null;
        BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
        while ((line = br.readLine())!=null)
        {
            ps.println(line);
        }
    }
}
</span>

客户端线程:

<span style="font-size:18px;">package com.example.administrator.openinternet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * Created by Administrator on 2015/7/23.
 * 客户端的线程
 */
public class ClientThread implements Runnable {
    private  Socket s ;
    BufferedReader br = null;

    public ClientThread(Socket s) throws IOException {
        this.s = s ;
        br = new BufferedReader(new InputStreamReader(s.getInputStream()));

    }

    /**
     * Starts executing the active part of the class' code. This method is
     * called when a thread is started that has been created with a class which
     * implements {@code Runnable}.
     */
    @Override
    public void run()
    {
        try
        {
            String content = null;
            while ((content = br.readLine())!=null)
            {
                System.out.println(content);
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
</span>

这就实现了简单的回话,其实可以继续扩展比如实现客户端和服务器端的数据的传递过几天更新过来

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 01:01:58

简易命令行界面的C/S聊天室的相关文章

Ajax PHP JavaScript MySQL实现简易的无刷新在线聊天室

思路 消息显示区 发消息 板块 消息显示 消息发送 优化 显示非重复性的数据 优化显示 加上滚动条 每次都显示最新消息 完整代码 前端代码 数据库表结构 服务器端代码 总结与展望 总结 展望 为更好的运用这两天学到的Ajax的相关的知识,就做了个简单的在线网络聊天室. 思路 实现聊天室,基本上就是通过Ajax来传递数据,让PHP来实现对数据的差入和查找,再交给前端JavaScript实现页面的更新,达到即时聊天的功能. 消息显示区 消息显示区就是一个DIV块,我们会借助Ajax获取到服务器端信息

php+websocket搭建简易聊天室实践

1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短连接和长连接.短连接一般可以用ajax实现,长连接就是websocket.短连接实现起来比较简单,但是太过于消耗资源.websocket高效不过兼容存在点问题.websocket是html5的资源 如果想要详细了解websocket长连接的原理请看https://www.zhihu.com/ques

vue + socket.io实现一个简易聊天室

vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位大大指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

php_3_“简易聊天室 ”实现的关键技术 详解

                  PHP+MySQL实现Internet上一个简易聊天室的关键技术  系统目标: 聊天室使用数据库汇集每个人的发言,并可将数据库内的发言信息显示在页面,让每个用户都可以看到,具体功能如下: a.用户登录:用户发言时显示其登录名信息 b.用户发言:用户输入说的话 c.显示发言信息:用户浏览所有发言信息 设计思路: (1).建立聊天室数据库及相关数据表 (2).实现用户登录页面(login.php) (3).实现发言页面(speak.php) (4).实现发言显示页

用HTML5 Web Storage作一个简易聊天室

前 言: 2个月前为了一个评论让我潜水(潜伏)博客园2年作了一次艰难的决定.注册了一个账号! 没事瞎逛博客园以及其他技术网站,发现一个不错的留言墙.就看了其中使用的技术.呀!惊呆了.居然是HTML5,完全没接触过呀! 再 言: 所以就搜了博客园相关文档,有如下信息: @#$^%&*( $&^^**(&( http://zzk.cnblogs.com/s?t=b&w=html5%20Storage #$%&^&*( %*(&()*%$ 资料太多了,你也

Socket编程(简易聊天室客户端/服务器编写、CocoaAsyncSocket)

Socket编程(简易聊天室客户端/服务器编写.CocoaAsyncSocket) 一.Socket 1.1 Socket简介 Socket就是为网络服务提供的一种机制.网络通信其实就是Socket间的通信,通信的两端都是Socket,数据在两个Socket间通过IO传输. 在Web服务大行其道的今天,调用Web服务的代价是高昂的,尤其是仅仅是抓取少量数据的时候尤其如此.而使用Socket,可以只传送数据本身而不用进行XML封装,大大降低数据传输的开销.Socket允许使用长连接,允许应用程序运

C 基于UDP实现一个简易的聊天室

引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少很多. 但是水也很深. 本文就当是一个demo整合帮助开发者回顾和继续了解 linux udp开发的基本流程. 首先我们来看看 linux udp 和 tcp的异同. /* 这里简单比较一下TCP和UDP在编程实现上的一些区别: TCP流程 建立一个TCP连接需要三次握手,而断开一个TCP则需要四个

socket.io入门,简易聊天室

介绍 通常我们web使用的是http协议,但是 HTTP 协议有一个缺陷:通信只能由客户端发起. 所以我们需要一个可以由服务端主动发出的协议,即WebSocket. WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种. Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯.通知与消息推送,实时分析等场景中有较为广泛的应用. socket.io 包含两个

docker搭建swoole简易聊天室

docker搭建swoole的简易聊天室 首先pull镜像 docker pull docker.io/kong36088/nginx-php7-swoole 创建容器 docker run --name {自己创建的名字} -p 9501:9501 -p 8089:80 -d -it kong36088/nginx-php7-swoole /bin/bash 进入容器 docker exec -it {容器名字或id} /bin/bash 进入容器之后进入nginx配置文件 cd /etc/n