参考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. LeetCode(30)-Pascal's Triangle

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...

  2. Unity脚本编程之——协程(Coroutine)

    本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html 专有名词: Coroutine 协程 Alpha 不透明度 当你调用一个函 ...

  3. async & await 异步编程的一点巧方法

    await 关键字不会创建新的线程,而是由Task任务或是FCL中的xxxAsync等方法创建的线程,而且这里创建的线程都是基于线程池创建的工作线程,属于后台线程. await关键字会阻塞/暂停调用它 ...

  4. Python_如何去除字符串里的空格

    个人想到的解决方法有两种,一种是 .replace(' old ',' new ')  第一个参数是需要换掉的内容比如空格,第二个是替换成的内容,可以把字符串中的空格全部替换掉. 第二种方法是像这样 ...

  5. 使用SecureCRT的SFTP在WINDOWS与LINUX之间传输文件(转载)

    参考文献: http://ice-k.iteye.com/blog/1068275 http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888 ...

  6. java并发包小结(一)

    java.util.concurrent 包含许多线程安全.高性能的并发构建块.换句话讲,创建 java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的 ...

  7. Spring AOP四种实现方式Demo详解与相关知识探究

    一.前言 在网络上看到一篇博客Spring实现AOP的4种方式,博主写的很通俗易懂,但排版实在抓狂,对于我这么一个对排版.代码格式有强迫症的人来说,实在是不能忍受~~~~(>_<)~~~~ ...

  8. JBOSS的启动和停止

    本实例使用的JBOSS版本是jboss-4.2.3.GA 假设条件 1.  已设置好JAVA_HOME环境变量 2.  已下载JBoss并且安装目录为:D:\Java\jboss-4.2.3.GA 启 ...

  9. WSL与Windows交互实践

    1. WSL是什么 2. WSL新特性 3. WSL管理配置 4. WSL交互 5. 解决方案  * 5.1 使用别名  * 5.2 多复制一份  * 5.3 重定向  * 5.4 symlink 6 ...

  10. (转)Go语言并发模型:使用 context

    转载自:https://segmentfault.com/a/1190000006744213 context golang 简介 在 Go http包的Server中,每一个请求在都有一个对应的 g ...