参考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. 用shell脚本挂载linux主机拷贝相应文件copy.sh

    #!/bin/sh # $1 MOUNTDIR $2 TARGETDIR $3 ERRORLOG #参数检查 if test $# -ne 3 then echo "argument che ...

  2. SpringBoot2.0之一 新建项目helloWorld

    SpringBoot 以简单快速很快获得了广大开发者的青睐,本套SpringBoot系列以最新的SpringBoot 2.0为基础,同时会提及不同版本下SpringBoot的修改和变化,如有理解不当的 ...

  3. className.class.getResourceAsStream与ClassLoader.getSystemResourceAsStream区别

    className.class.getResourceAsStream : 一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件conf ...

  4. IT咨询顾问:一次吐血的项目救火

    年后的一个合作公司上线了一个子业务系统,对接公司内部的单点系统.我收到该公司的技术咨询:项目启动后没有规律的突然无法登录了,重新启动后,登录一断时间后又无法重新登录,对方技术人员一头雾水不知道什么原因 ...

  5. 温故而后知新——对ado.net中常用对象的一些解释

    在使用ado.net连接数据库获取数据,一般的步骤是: 1.设置好web.config    //用来设置服务器数据库的地址以及登录名密码 2.创建Connection对象    //用来创建访问数据 ...

  6. 论MVC中的传值

    2个页面分别为Father.cshtml.Child.cshtml 2个控制器分别为FatherController.cs.ChildController.cs 1个js,为Father.js 一.F ...

  7. DBC的故事

    1.DBC定义 DBC(data base CAN)是汽车ECU间进行CAN通讯的报文内容,有了它相互之间才能听懂. 2.DBC查看 DBC是文本文件,可以用记事本打开,一般都用CANdb++,可以更 ...

  8. printf("Hello 2018!");

    月考 has Boom! 要全心准备期末考试,到年前是不能再看Blog了 新年加油!!! 不要感冒 :joy:

  9. 用js来实现那些数据结构16(图02-图的遍历)

    上一篇文章我们简单介绍了一下什么是图,以及用JS来实现一个可以添加顶点和边的图.按照惯例,任何数据结构都不可或缺的一个point就是遍历.也就是获取到数据结构中的所有元素.那么图当然也不例外.这篇文章 ...

  10. 简明4步,让Python的好朋友Pycharm变得更加雅观!

    跟着人工智能/机械学习的兴起,Python再次取得广泛程序员的关注.而JetBrains出品的PyCharm无疑是最好用的Python IDE之一. 把本身的IDE装备安排得既有逼格又雅观,这是每个P ...