-------------siwuxie095

 
 

 
 

 
 

 
 

 
 

 
 

 
 

工程名:TestMyServerSocket

包名:com.siwuxie095.socket

类名:MyServerSocket.java(主类)、ServerListener.java、ChatSocket.java

 
 

 
 

工程结构目录如下:

 
 

 
 

 
 

 
 

 
 

MyServerSocket.java(主类):

 
 

package com.siwuxie095.socket;

 
 

/**

* 聊天服务器,仅能向客户端发送数据

*

* @author siwux

*

*/

 
 

public class MyServerSocket {

 

/**

* 这是主类(主线程),启动线程ServerListener进行监听,

* 当有Socket对象进行连接时,在线程ServerListener中

* 启动线程ChatSocket

*

* @param args

*/

 
 

public static
void main(String[] args) {

 

//运行线程ServerListener,使用匿名对象

new ServerListener().start();

}

 
 

}

 
 

 
 

 
 

ServerListener.java:

 
 

package com.siwuxie095.socket;

 
 

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

 
 

import javax.swing.JOptionPane;

 
 

//创建线程 ServerListener,将有阻塞的代码放到这个独立的线程中

public class ServerListener extends Thread {

 
 

// 复写run()

@Override

public
void run() {

try {

 
 

// 端口的范围:1~65535,通常都指定较大的数字,

// 这样和较小的或系统预留的端口分开

// 有异常抛出,用 try catch 捕获

ServerSocket serverSocket = new ServerSocket(12345);

 
 

 

// ServerSocket创建完成后需要侦听客户端的连接

// 调用accept()方法,这是一个阻塞的方法,

// 会阻塞当前的线程,对于有阻塞的代码,应该放到独立的线程中

//(ServerListener 就是一个独立的线程)

// 返回值是Socket类型,创建以接收返回值

// 当accept()被执行且socket被赋值,说明有客户端连接

//每当有一个客户端连接到ServerSocket,accept()都会返回一个新的Socket对象

//如果有多个客户端来连接当前的服务器ServerSocket,就会有多个Socket对象出现

//需要一个while循环来循环监听

while (true) {

 

Socket socket = serverSocket.accept();

 
 

// 建立连接时

// 弹出提示框:有客户端连接到本机的 12345 端口

JOptionPane.showMessageDialog(null, "有客户端连接到本机的 12345 端口");

 

//由于每一个socket要与一个独立的客户端进行通信

//所以要将socket传递给新的线程:ChatSocket(用于Socket通信)

//每一个socket都有一个独立的ChatSocket线程

//每一个ChatSocket线程之间是相互独立的,它们不能相互沟通数据

//运行该线程,使用匿名对象

new ChatSocket(socket).start();

 

}

 

 
 

} catch (IOException e) {

e.printStackTrace();

}

 
 

}

 
 

}

 
 

 
 

 
 

ChatSocket.java:

 
 

package com.siwuxie095.socket;

 
 

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.UnsupportedEncodingException;

import java.net.Socket;

 
 

/**

* 代码段(4)一直包装到带缓冲的字符流,输出时需要flush进行强制输出

* 代码段(3)是简单的字节流进行输出

*

* (4)等效于(3)等效于(1)加(2)

*

* (4)=(3)=(1)+(2)

*

* 主要使用(4),其他注释起来

*

* @author siwux

*

*/

 
 

//创建用于Socket通信的线程:ChatSocket

public class ChatSocket extends Thread {

 

Socket socket;

 

//创建构造方法,传入Socket对象

public ChatSocket(Socket socket) {

this.socket=socket;

}

 

 

 

//(1)

public
void output(String out) {

try {

//socket.getOutputStream() 即 OutputStream

//实际上是 OutputStream.write() 即 os.write()

//为 getBytes()指定编码

//有异常抛出,用 try catch 捕获

socket.getOutputStream().write(out.getBytes("UTF-8"));

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

 

 

 

//复写run()方法

@Override

public
void run() {

 

// //(2)

// int count=0;

// while (true) {

// output("loop:"+count+"-");

// count++;

// try {

// sleep(1000);

// } catch (InterruptedException e) {

// e.printStackTrace();

// }

// }

 

 

 

 

// //(3)

// try {

// OutputStream os=socket.getOutputStream();

// int count=0;

// while (true) {

// String outString="loop:"+count+"-";

// byte outByte[]=outString.getBytes("UTF-8");

// os.write(outByte);

// count++;

// sleep(1000);

//

// }

//

// } catch (IOException e) {

// e.printStackTrace();

// } catch (InterruptedException e) {

// e.printStackTrace();

// }

 

 

 

 

//(4)

try {

 

//对当前的Socket执行
数据输出相关功能的包装

//使用getOutputStream()获取输出流,通过输出流向外输出数据

//返回值是OutputStream类型,创建以接收返回值

OutputStream os=socket.getOutputStream();

 

//创建一个BufferedWriter作为数据的输出,传入匿名对象,指定编码,层层包装

BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));

 

 

//通过BufferedWriter可以在Socket中直接输出一行字符串

int count=0;

//一直循环

while (true) {

 

//让BufferedWriter输出字符串

bw.write("loop:"+count+"-");

//因为带缓冲,所以需要强制输出,不然无法输出

bw.flush();

//1秒执行一次

//有异常抛出,用 try catch 捕获

sleep(1000);

count++;

 

}

 

} catch (IOException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

}

 

 

}

}

 
 

 
 

运行后,终止按钮(Terminate)长亮,即 当前程序正在运行 且 没有停止

 
 

 
 

而且,此时也没有任何提示框,即当前程序被阻塞在
ServerListener.java 的:

Socket socket=serverSocket.accept();

 
 

 
 

 
 

打开
CMD 窗口,输入:telnet 127.0.0.1 12345

telnet localhost 12345

(即
本机地址+端口),回车。此时,会弹框提示:

 
 

 
 

 
 

 
 

点击确定,CMD 窗口开始无限循环输出:

 
 

 
 

 
 

 
 

此时程序并未停止,可以继续打开多个
CMD 窗口进行连接,

相当于新建客户端,也是从一开始进行输出

 
 

点击
终止按钮(Terminate),可结束运行

 
 

 
 

 
 

 
 

 
 

【made by siwuxie095】

使用ServerSocket建立聊天服务器(一)的更多相关文章

  1. Socket 基础解析使用ServerSocket建立聊天服务器

    很简单的教程哦! 1.socket 简介 Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求.ServerSocket 用于 ...

  2. 使用 ServerSocket 建立聊天服务器-1

    1.代码目录 2.ChatSocket.java --------------------------------------------------------------------------- ...

  3. 使用ServerSocket建立聊天服务器(二)

    -------------siwuxie095                         工程名:TestMyServerSocket 包名:com.siwuxie095.socket 类名:M ...

  4. 使用 ServerSocket 建立聊天服务器-2

    1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...

  5. 使用Java建立聊天客户端

    ---------------siwuxie095                             关于 聊天服务器,详见本人博客的分类:来一杯Java, 里面的 使用ServerSocket ...

  6. [CareerCup] 8.7 Chat Server 聊天服务器

    8.7 Explain how you would design a chat server. In particular, provide details about the various bac ...

  7. openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...

  8. 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    原文:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 随笔-150  评论- ...

  9. 使用rabbitmq实现集群im聊天服务器消息的路由

    这个地址图文会更清晰:https://www.jianshu.com/p/537e87c64ac7 单机系统的时候,客户端和连接都有同一台服务器管理.   image.png 在本地维护一份userI ...

随机推荐

  1. sql语句中as的用法和作用

    最近做项目中,偶然发现在SQL语句中出现了as这个词,一直以来没怎么关注是什么意思,毕竟影响不大,今天有空,就在网上查了一些资料,大概有了一些的了解 我们的Sql语句在很多数据库中都是通用的,比如像M ...

  2. 20180831_jar包冲突2_天安微信httpclient冲突

    一.异常现象 微信项目需要向腾讯服务器发送请求获取token. 但是在请求的时候抛了个异常: <2018-8-30 下午05时39分18秒 CST> <Notice> < ...

  3. 20165210 Java第三周学习总结

    20165210 Java第三周学习总结 教材学习内容总结 - 第四章学习总结 编程语言的几个发展阶段: 面向机器语言 面向过程语言 面向对象语言 类: 类声明: class People { ... ...

  4. Python日志统计

    #!/usr/bin/env python # coding:utf-8   import sys,time   class DisplayFormat(object):       def form ...

  5. python 获取本机ip地址的方法(Unix 平台)

    #!/usr/bin/python import socket import fcntl import struct def get_ip_address(ifname): s = socket.so ...

  6. 使用window.print()后,未关闭打印页面,原网页不能操作

    使用window.print()后,未关闭打印页面,原网页不能操作,此时可以试着用window.location.reload()重新加载页面解决问题.

  7. 使用POI导出excel进阶篇

    进阶篇就是涉及到合并单元格了.就是某一列相同的单元格需要合并为一个,并分为多个sheet. 效果如图: 直接上代码,需要提供的数据自己搞,传到工具类里面就好. JcExcelVoSuper.java ...

  8. Python函数-input()

    input([prompt]) 如果[prompt]是存在的,它被写入标准输出中没有换行.然后函数读取输入,将其转换为一个字符串,然后返回. >>> s = input('--> ...

  9. SQL Server 学习系列之五

    SQL Server 学习系列之五 SQL Server 学习系列之一(薪酬方案+基础) SQL Server 学习系列之二(日期格式问题) SQL Server 学习系列之三(SQL 关键字) SQ ...

  10. PHP实现图片压缩的两则实例(转)

    本文介绍了PHP实现图片压缩的两种方法,读者可以根据具体应用参考或加以改进,以适应自身应用需求!废话不多说,主要代码部分如下: 实例1: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 ...