java Socket多线程聊天程序
以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
一个非常简单的java聊天程序,有客户端和服务器端,目前只有群聊功能,其他的所有功能都可以在这个基础上添加,现在我分享出来主要是为了保持一个最简单的java聊天程序便于初学者学习,界面也非常的简洁,只有两个文件,主要是用了socket,java多线程,知识点不是很多,很适合初学者

服务器端程序:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; /**
* @Auther: 李景然
* @Date: 2018/5/17 10:12
* @Description:
*/
public class TKServer extends JFrame implements ActionListener { private Map<Integer, Socket> clients = new HashMap<Integer, Socket>();
private JTextArea msg = new JTextArea("服务器消息接收器\r\n\n");
private JTextArea input = new JTextArea();
private JButton msgSend = new JButton("发送群消息"); public TKServer() {
// TODO Auto-generated constructor stub
this.setVisible(true);
this.setTitle("服务器");
this.setSize(, );
this.setResizable(true);
this.setLayout(new FlowLayout());
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
super.windowClosing(arg0);
System.exit();
}
});
input.setColumns();
input.setRows();
input.setAutoscrolls(true);
msgSend.addActionListener(this);
msgSend.setActionCommand("sendMsg");
msg.setAutoscrolls(true);
msg.setColumns();
msg.setRows(); JScrollPane spanel = new JScrollPane(msg);
JScrollPane editpanel = new JScrollPane(input);
this.add(spanel);
this.add(editpanel);
this.add(msgSend);
} public static void main(String[] args) { new TKServer().listenClient();
} public void listenClient() { String temp = "";
try {
//server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
// 定义一个ServerSocket监听在端口8899上
ServerSocket server = new ServerSocket();
while (true) {
System.out.println("服务器端正在监听");
Socket socket = server.accept();
clients.put(socket.getPort(), socket);
temp = "客户端" + socket.getPort() + " 连接";
this.apppendMsg(temp);
new mythread(socket, this).start();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
} public void apppendMsg(String msg) { this.msg.append(msg + "\r\n");
} public void sendMsgToAll(Socket fromSocket, String msg) { Set<Integer> keset = this.clients.keySet();
java.util.Iterator<Integer> iter = keset.iterator();
while (iter.hasNext()) {
int key = iter.next();
Socket socket = clients.get(key);
if (socket != fromSocket) {
try {
if (socket.isClosed() == false) {
if (socket.isOutputShutdown() == false) { Writer writer = new OutputStreamWriter(
socket.getOutputStream());
writer.write(msg);
writer.flush();
}
}
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
} @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub String temp = "";
if ("sendMsg".equals(e.getActionCommand())) {
if ((temp = this.input.getText()) != null) {
System.out.println("开始向客户端群发消息");
this.apppendMsg("服务器-->" + temp);
Set<Integer> keset = this.clients.keySet();
java.util.Iterator<Integer> iter = keset.iterator();
while (iter.hasNext()) {
int key = iter.next();
Socket socket = clients.get(key);
try {
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write(temp);
writer.flush();
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
this.input.setText("");
}
}
}
} class mythread extends Thread { private Socket socket = null;
private TKServer server = null;
private InputStreamReader reader = null;
char chars[] = new char[];
int len;
private String temp = null; public mythread(Socket socket, TKServer server) {
// TODO Auto-generated constructor stub this.socket = socket;
this.server = server;
init();
} private void init() { try {
reader = new InputStreamReader(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @Override
public void run() {
// TODO Auto-generated method stub System.out.println("子线程开始工作");
while (true) {
try {
System.out.println("服务器 线程" + this.getId() + "-->开始从客户端读取数据——>");
while ((len = ((Reader) reader).read(chars)) != -) {
temp = new String(chars, , len);
System.out.println("客户端" + socket.getPort() + "说-->" + temp);
server.apppendMsg("客户端" + socket.getPort() + "说-->" + temp);
server.sendMsgToAll(this.socket, "客户端" + socket.getPort() + "说-->" + temp);
}
if (socket.getKeepAlive() == false) {
((Reader) reader).close();
temp = "客户端" + socket.getPort() + "-->退出";
server.apppendMsg(temp);
socket.close();
this.stop();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
try {
((Reader) reader).close();
socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}
客户端程序:
/**
* @Auther: 李景然
* @Date: 2018/5/17 10:15
* @Description:
*/ import java.awt.FlowLayout; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
import java.net.UnknownHostException; import javax.swing.*; public class TKClient extends JFrame implements ActionListener { // 为了简单起见,所有的异常都直接往外抛
String host = "127.0.0.1"; // 要连接的服务端IP地址
int port = ; // 要连接的服务端对应的监听端口
mythread thread = null;
Socket client = null;
Writer writer = null; private JTextArea msg = new JTextArea("客户端消息接收器\r\n\n");
private JTextArea input = new JTextArea();
private JButton msgSend = new JButton("发送群消息"); public TKClient() {
// TODO Auto-generated constructor stub initSocket();
this.setVisible(true);
this.setTitle("客户端");
this.setSize(, );
this.setResizable(true);
this.setLayout(new FlowLayout());
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
super.windowClosing(arg0);
try {
if (client != null) {
client.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (thread != null) {
thread.stop();
}
System.exit();
}
});
input.setColumns();
input.setRows();
input.setAutoscrolls(true);
msgSend.addActionListener(this);
msgSend.setActionCommand("sendMsg");
msg.setAutoscrolls(true);
msg.setColumns();
msg.setRows();
JScrollPane spanel = new JScrollPane(msg);
JScrollPane editpanel = new JScrollPane(input);
this.add(spanel);
this.add(editpanel);
this.add(msgSend);
} /**
* @param args
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub new TKClient();
} public void initSocket() { try {
client = new Socket(this.host, this.port);
writer = new OutputStreamWriter(client.getOutputStream());
// 建立连接后就可以往服务端写数据了
thread = new mythread(client, this);
thread.start();
this.appendMsg("已连上服务器");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.appendMsg("不能连接上服务器");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.appendMsg("不能连接上服务器");
}
} public void appendMsg(String msg) { this.msg.append(msg + "\r\n");
} @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub String temp = "";
try {
if ("sendMsg".equals(e.getActionCommand())) {
if ((temp = this.input.getText()) != null) {
writer.write(temp);
writer.flush();
this.appendMsg("我(" + this.client.getLocalPort() + ")说——>" + temp);
this.input.setText("");
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} class mythread extends Thread { private Socket socket = null;
private Reader reader = null;
private int len = ;
char chars[] = new char[];
private TKClient client = null;
private String temp = ""; public mythread(Socket socket, TKClient client) {
// TODO Auto-generated constructor stub this.socket = socket;
this.client = client;
try {
reader = new InputStreamReader(socket.getInputStream());
} catch (Exception e) {
// TODO: handle exception
}
} @Override
public void run() {
// TODO Auto-generated method stub super.run();
System.out.println("客户端 子线程" + this.getId() + "-->开始工作");
while (true) {
try {
if (socket.isClosed() == false) {
if (socket.isInputShutdown() == false) {
while ((len = ((Reader) reader).read(chars)) != -) {
temp = "服务器说——>" + new String(chars, , len);
client.appendMsg(temp);
System.out.println();
}
}
} else {
if (socket.getKeepAlive() == false) {
reader.close();
socket.close();
this.stop();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
java Socket多线程聊天程序的更多相关文章
- Java Socket 多线程聊天室
本来这次作业我是想搞个图形界面的,然而现实情况是我把题意理解错了,于是乎失去了最初的兴致,还是把程序变成了功能正确但是“UI”不友好的console了,但是不管怎么样,前期的图形界面的开发还是很有收获 ...
- Java使用TCP聊天程序
前面使用了UDP进行通信的聊天程序 现在做一个用TCP进行通信的聊天程序 原理: ServerSocket Socket 1.开一个线程监听端口,准备接收消息 2.不断接受消息发送到目的端口 P.S. ...
- java socket 多线程网络传输多个文件
http://blog.csdn.net/njchenyi/article/details/9072845 java socket 多线程网络传输多个文件 2013-06-10 21:26 3596人 ...
- 用Java实现多线程服务器程序
一.Java中的服务器程序与多线程 在Java之前,没有一种主流编程语言能够提供对高级网络编程的固有支持.在其他语言环境中,实现网络程序往往需要深入依赖于操作平台的网络API的技术中去,而Java提供 ...
- Java使用UDP聊天程序
主要想测试Java UDP通信.Java UDP使用DatagramSocket和DatagramPacket完成UDP通信 主要思路: 1.本机通信,ip地址为:127.0.0.1 2.开一个线程监 ...
- [置顶]
Chat Room:基于JAVA Socket的聊天室设计
d0304 更新功能实现 d0312 更新部分图片&UI设计部分 d0318 更新功能实现 d1222 实现添加好友功能.实现注册功能.修改大量BUG github:https://githu ...
- java+socket 简易聊天工具
1.服务器端程序 package com.test3; import java.io.*; import java.net.*; import java.awt.*; import java.awt. ...
- java socket编程--聊天小案例
很久以前写过socket聊天室,都快忘完了,心血来潮又重新写一遍. 服务器端: package com.fancy; import java.io.BufferedReader; import jav ...
- java Socket Udp聊天
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import jav ...
随机推荐
- 用shell脚本挂载linux主机拷贝相应文件copy.sh
#!/bin/sh # $1 MOUNTDIR $2 TARGETDIR $3 ERRORLOG #参数检查 if test $# -ne 3 then echo "argument che ...
- SpringBoot2.0之一 新建项目helloWorld
SpringBoot 以简单快速很快获得了广大开发者的青睐,本套SpringBoot系列以最新的SpringBoot 2.0为基础,同时会提及不同版本下SpringBoot的修改和变化,如有理解不当的 ...
- className.class.getResourceAsStream与ClassLoader.getSystemResourceAsStream区别
className.class.getResourceAsStream : 一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件conf ...
- IT咨询顾问:一次吐血的项目救火
年后的一个合作公司上线了一个子业务系统,对接公司内部的单点系统.我收到该公司的技术咨询:项目启动后没有规律的突然无法登录了,重新启动后,登录一断时间后又无法重新登录,对方技术人员一头雾水不知道什么原因 ...
- 温故而后知新——对ado.net中常用对象的一些解释
在使用ado.net连接数据库获取数据,一般的步骤是: 1.设置好web.config //用来设置服务器数据库的地址以及登录名密码 2.创建Connection对象 //用来创建访问数据 ...
- 论MVC中的传值
2个页面分别为Father.cshtml.Child.cshtml 2个控制器分别为FatherController.cs.ChildController.cs 1个js,为Father.js 一.F ...
- DBC的故事
1.DBC定义 DBC(data base CAN)是汽车ECU间进行CAN通讯的报文内容,有了它相互之间才能听懂. 2.DBC查看 DBC是文本文件,可以用记事本打开,一般都用CANdb++,可以更 ...
- printf("Hello 2018!");
月考 has Boom! 要全心准备期末考试,到年前是不能再看Blog了 新年加油!!! 不要感冒 :joy:
- 用js来实现那些数据结构16(图02-图的遍历)
上一篇文章我们简单介绍了一下什么是图,以及用JS来实现一个可以添加顶点和边的图.按照惯例,任何数据结构都不可或缺的一个point就是遍历.也就是获取到数据结构中的所有元素.那么图当然也不例外.这篇文章 ...
- 简明4步,让Python的好朋友Pycharm变得更加雅观!
跟着人工智能/机械学习的兴起,Python再次取得广泛程序员的关注.而JetBrains出品的PyCharm无疑是最好用的Python IDE之一. 把本身的IDE装备安排得既有逼格又雅观,这是每个P ...