可以實現(xiàn)的方式很多. 說一個簡單的方案,思路如下
成都創(chuàng)新互聯(lián)公司主要從事網(wǎng)站設計、網(wǎng)站建設、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務白堿灘,10余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:028-86922220
比如給數(shù)據(jù)庫添加1個字段. 比如字段名為 online . 值默認為false
當賬號A連接服務器, 登陸后 . 把A的onlie字段設置為true ,如果賬號A和服務器斷開連接 , 那么把online字段設置為false.
那么每次登陸時,要檢查該賬號對應的online字段, 為false.才允許登陸, 否則提示用戶, 不能重復登陸
這個東西做起來并沒有什么難度,關鍵點是通信那一塊。
建議消息用服務器轉發(fā)的方式。每個登陸用戶與服務器采用短連接通信。
其他沒什么重要的了,你自己努力一下,2天大概就能做的很像樣了。如果做的過程中有問題,可以問我。
如果你想做到T訊那樣,就不現(xiàn)實了,倒不是說功能多,只因為他的通信方式要復雜很多。比如說跨局域網(wǎng)的UDP通信,那是很復雜的。你還要理解網(wǎng)絡,理解路由器,才可以哦。
簡單得很的那種要不要?就像用來應對考試一樣。
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();
}?
}
}
}
兩個類,實現(xiàn)交互不帶界面的簡單容易讓你了解核心的知識
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);//實現(xiàn)Socket
List sockets = new ArrayList();//創(chuàng)建一個集合,保存文字消息
while(true){
Socket s = ss.accept();//監(jiān)聽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循環(huán)遍歷集合
Socket s2 = (Socket)sockets.get(i);//創(chuàng)建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);//創(chuàng)建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