参考JAVA 通过 Socket 实现 TCP 编程

参考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多线程聊天程序的更多相关文章

  1. Java Socket 多线程聊天室

    本来这次作业我是想搞个图形界面的,然而现实情况是我把题意理解错了,于是乎失去了最初的兴致,还是把程序变成了功能正确但是“UI”不友好的console了,但是不管怎么样,前期的图形界面的开发还是很有收获 ...

  2. Java使用TCP聊天程序

    前面使用了UDP进行通信的聊天程序 现在做一个用TCP进行通信的聊天程序 原理: ServerSocket Socket 1.开一个线程监听端口,准备接收消息 2.不断接受消息发送到目的端口 P.S. ...

  3. java socket 多线程网络传输多个文件

    http://blog.csdn.net/njchenyi/article/details/9072845 java socket 多线程网络传输多个文件 2013-06-10 21:26 3596人 ...

  4. 用Java实现多线程服务器程序

    一.Java中的服务器程序与多线程 在Java之前,没有一种主流编程语言能够提供对高级网络编程的固有支持.在其他语言环境中,实现网络程序往往需要深入依赖于操作平台的网络API的技术中去,而Java提供 ...

  5. Java使用UDP聊天程序

    主要想测试Java UDP通信.Java UDP使用DatagramSocket和DatagramPacket完成UDP通信 主要思路: 1.本机通信,ip地址为:127.0.0.1 2.开一个线程监 ...

  6. [置顶] Chat Room:基于JAVA Socket的聊天室设计

    d0304 更新功能实现 d0312 更新部分图片&UI设计部分 d0318 更新功能实现 d1222 实现添加好友功能.实现注册功能.修改大量BUG github:https://githu ...

  7. java+socket 简易聊天工具

    1.服务器端程序 package com.test3; import java.io.*; import java.net.*; import java.awt.*; import java.awt. ...

  8. java socket编程--聊天小案例

    很久以前写过socket聊天室,都快忘完了,心血来潮又重新写一遍. 服务器端: package com.fancy; import java.io.BufferedReader; import jav ...

  9. java Socket Udp聊天

    import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import jav ...

随机推荐

  1. 模拟IC芯片设计开发的流程

    模拟IC芯片设计开发的流程 IC的设计,模拟和数字, 还有混合IC, 在设计方法, 注意点, 工具等有明显的区别, 我主要以模拟无线接收IC系统设计为例说明. 一个IC芯片的设计开发大致包括如下步骤. ...

  2. Linux的chkconfig命令详解

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法: chkconfig [--a ...

  3. 解决XMind运行卡顿

    问题 XMind是一款很好用的脑图工具,它是基于eclipse开发的,而且基础功能是免费的.最近我安装了XMind 8 Pro,但是发现在Mac上运行有卡顿. 解决方式 解决这个问题的思路也很简单,软 ...

  4. Linux的硬盘分区

    关于硬盘分区,这里先只讨论硬盘分区的方法在linux环境下,其他知识以后也会陆续说到 首先我们通过 df 命令查看一下硬盘的使用情况,在安装硬盘分区后做比较用 [root@bogon ~]# df - ...

  5. STL读书笔记

    vector - 会自动增长的数组 vector又称为向量数组,他是为了解决程序中定义的数组是不能动态改变大小这个缺点而出现的.一般程序实现是在类创建的时候同时创建一个定长数组,随着数据不断被写入,一 ...

  6. element.dispatchEvent is not a function的解决

    Firebug中的出错提示: element.dispatchEvent is not a function element.dispatchEvent(event); prototype.js (第 ...

  7. ubuntu 13.10 install wireshark

    ubuntu 13.10 install wireshark 今天在使用java jsoup操作remote server的是否,在本地执行可以成功返回内容,然后打成jar包,使用shell在 ser ...

  8. Niop2017初赛滚粗记

    初赛踢蹬滚粗 TOT (╯°Д°)╯︵┻━┻ ヽ(`Д´)ノ︵ ┻━┻ ┻━┻ 排序啊排序,净是排序,自打我学了C++就再没学过排序!!wtf! (╯°Д°)╯︵ /(.□ . )我tm怎么知道建国那 ...

  9. Java并发-任务执行

    大多数的应用程序都是围绕"任务执行"来构造的:任务常常是一些抽象的并且离散的工作单元.我们把应用程序的工作分解到多个任务中,可以简化程序的组织结构,提供一种自然的事物便捷来优化错误 ...

  10. 基于Cloudera Search设计数据灾备方案

    当实际项目上线到生产环境中,难以避免一些意外情况,如数据丢失.服务器停机等.对于系统的搜索服务来说,当遇到停机的情况意味着在停机这段时间内,用户都不能通过搜索的相关功能进行访问数据,停机意味着将这一段 ...