十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
可以实现的方式很多. 说一个简单的方案,思路如下
成都创新互联公司主要从事网站设计、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务白碱滩,10余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:028-86922220
比如给数据库添加1个字段. 比如字段名为 online . 值默认为false
当账号A连接服务器, 登陆后 . 把A的onlie字段设置为true ,如果账号A和服务器断开连接 , 那么把online字段设置为false.
那么每次登陆时,要检查该账号对应的online字段, 为false.才允许登陆, 否则提示用户, 不能重复登陆
这个东西做起来并没有什么难度,关键点是通信那一块。
建议消息用服务器转发的方式。每个登陆用户与服务器采用短连接通信。
其他没什么重要的了,你自己努力一下,2天大概就能做的很像样了。如果做的过程中有问题,可以问我。
如果你想做到T讯那样,就不现实了,倒不是说功能多,只因为他的通信方式要复杂很多。比如说跨局域网的UDP通信,那是很复杂的。你还要理解网络,理解路由器,才可以哦。
简单得很的那种要不要?就像用来应对考试一样。
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
boolean started = false;
ServerSocket ss = null;
ListClient clients = new ArrayListClient();
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
ss = new ServerSocket(8888);
started = true;
} catch (BindException e) {
System.out.println("端口使用中....");
System.out.println("请关掉相关程序并重新运行服务器!");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while(started) {
Socket s = ss.accept();
Client c = new Client(s);
System.out.println("a client connected!");
new Thread(c).start();
clients.add(c);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client implements Runnable {
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
System.out.println(str);
for(int i=0; iclients.size(); i++) {
Client c = clients.get(i);
c.send(str);
}
}
} catch (EOFException e) {
System.out.println("Client closed!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(dis != null) dis.close();
if(dos != null) dos.close();
if(s != null) {
s.close();
//s = null;
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
客户端,开两个就能聊了……
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class ChatClient extends Frame {
Socket s = null;
DataOutputStream dos = null;
DataInputStream dis = null;
private boolean bConnected = false;
TextField tfTxt = new TextField();
TextArea taContent = new TextArea();
Thread tRecv = new Thread(new RecvThread());
public static void main(String[] args) {
new ChatClient().launchFrame();
}
public void launchFrame() {
setLocation(400, 300);
this.setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
disconnect();
System.exit(0);
}
});
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
tRecv.start();
}
public void connect() {
try {
s = new Socket("127.0.0.1", 8888);
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
System.out.println("connected!");
bConnected = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tfTxt.getText().trim();
tfTxt.setText("");
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
private class RecvThread implements Runnable {
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
taContent.setText(taContent.getText() + str + '\n');
}
} catch (SocketException e) {
System.out.println("bye!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
两个类,实现交互不带界面的简单容易让你了解核心的知识
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MutiChat
{
public static void main(String[] args)
{
MutiChat mc = new MutiChat();
mc.receive().start();
mc.send().start();
}
/**
* 接收信息
*
* @return
*/
private Thread receive()
{
return new Thread()
{
public void run()
{
ServerSocket server_socket = null;
Socket sk = null;
BufferedReader in = null;
try
{
server_socket = new ServerSocket(7777);
sk = server_socket.accept();
in = new BufferedReader(new InputStreamReader(sk
.getInputStream()));
while (true)
{
String str = in.readLine();
System.out.println(str);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
};
}
private Thread send()
{
return new Thread()
{
public void run()
{
Socket client_socket = null;
BufferedReader in = null;
PrintWriter out = null;
while (true)
{
try
{
client_socket = new Socket("127.0.0.1", 8888);
in = new BufferedReader(
new InputStreamReader(System.in));
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(client_socket
.getOutputStream())), true);
while (true)
{
String str = in.readLine();
out.println(str);
}
} catch (Exception e)
{
try
{
Thread.sleep(1000);
} catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
};
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MutiChat2
{
public static void main(String[] args)
{
MutiChat2 mc = new MutiChat2();
mc.receive().start();
mc.send().start();
}
/**
* 接收信息
*
* @return
*/
private Thread receive()
{
return new Thread()
{
public void run()
{
ServerSocket server_socket = null;
Socket sk = null;
BufferedReader in = null;
try
{
server_socket = new ServerSocket(8888);
sk = server_socket.accept();
in = new BufferedReader(new InputStreamReader(sk
.getInputStream()));
while (true)
{
String str = in.readLine();
System.out.println(str);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
};
}
private Thread send()
{
return new Thread()
{
public void run()
{
Socket client_socket = null;
BufferedReader in = null;
PrintWriter out = null;
while (true)
{
try
{
client_socket = new Socket("127.0.0.1", 7777);
in = new BufferedReader(
new InputStreamReader(System.in));
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(client_socket
.getOutputStream())), true);
while (true)
{
String str = in.readLine();
out.println(str);
}
} catch (Exception e)
{
try
{
Thread.sleep(1000);
} catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
};
}
}
下面这个是可以带图形界面的
Server:
package ChatIV;
import java.net.*;
import java.io.*;
import java.util.*;
//广播聊天室服务端
public class Server {
public static void main(String args[]){
try {
ServerSocket ss = new ServerSocket(8186);//实现Socket
List sockets = new ArrayList();//创建一个集合,保存文字消息
while(true){
Socket s = ss.accept();//监听8186
sockets.add(s);//向集合中添加Socket的对象S,把听到的内容保存到集合中
Thread t1 = new ChatThread(s,sockets);//线程
t1.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ChatThread extends Thread{
Socket s;
List sockets;
public ChatThread(Socket s,List sockets){
this.s=s;
this.sockets=sockets;
}
public void run(){
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));//包装成字符流
while(true){
String str = in.readLine();//读BufferedReader
for(int i=0;isockets.size();i++){//利用For循环遍历集合
Socket s2 = (Socket)sockets.get(i);//创建Socket对象S2,强转成Socket,并获取下标
PrintWriter out = new PrintWriter(s2.getOutputStream());//文本流输出
out.println(str);//打印字符
out.flush();//刷新该流的缓冲
}
}
} catch (IOException e) {}
finally{
try {
s.close();
} catch (IOException e) {}
}
}
}
Client:
package ChatIV;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
//广播聊天室客户端
public class Client {
JTextArea jta;
JTextField jtf;
BufferedReader in;
PrintWriter out;
//Swing画一个界面
private void initGUI(){
JFrame f=new JFrame("Client");
f.setSize(400,300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jta=new JTextArea();
jta.setEditable(false);
f.add(new JScrollPane(jta));
jtf=new JTextField();
f.add(jtf,"South");
f.setVisible(true);
jtf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
String text=jtf.getText();
jtf.setText("");
out.println(text);
out.flush();
}
});
}
//连接初始化
private void initNet(){
try {
Socket s = new Socket("127.0.0.1",8186);//创建Socket端口8186,端口号随意,避免常用端口即可
out = new PrintWriter(s.getOutputStream());//文本流输出,利用Socket对象获得getOutputStream()
in = new BufferedReader(new InputStreamReader(s.getInputStream()));//包装成字符流
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//消息接收
private void receive(){
try {
while(true){
String str = in.readLine();//读BufferedReader
if(str==null){
return ;
}
jta.append("说"+str+"\n");//加载到JTextArea中,显示
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Client(){
this.initGUI();
this.initNet();
}
public static void main(String args[]){
Client c = new Client();
c.receive();
}
}
1、swing的界面可以直接用netbeans画出来嘛。
2、可以把输出的聊天内容都放在一个StringBuffer里,每打出一句话,就把这句话追加在StringBuffer,然后把StringBuffer里的内容输出到Textarea中。
3、好友列表可以用JList