① java中做客戶與客戶的聊天對話,利用socket實現了客戶的群發功能,怎麼利用map給指定的客戶發消息
Socket非常類似於電話插座。以一個國家級電話網為例,電話的通話雙方相當於相互通信的2個進程,區號是它的網路地址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於Socket號。任何用戶在通話之前,首先要佔有一部電話機,相當於申請一個Socket;同時要知道對方的號碼,相當於對方有一個固定的Socket。然後向對方撥號呼叫,相當於發出連接請求(假如對方不在同一區內,還要撥對方區號,相當於給出網路地址)。假如對方在場並空閑(相當於通信的另一主機開機且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當於連接成功。雙方通話的過程,是一方向電話機發出信號和對方從電話機接收信號的過程,相當於向Socket發送數據和從socket接收數據。通話結束後,一方掛起電話機相當於關閉Socket,撤消連接。
在電話系統中,一般用戶只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,話音傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與Socket機制非常相似。Socket利用網間網通信設施實現進程通信,但它對通信設施的細節毫不關心,只要通信設施能提供足夠的通信能力,它就滿足了。
至此,我們對Socket進行了直觀的描述。抽象出來,Socket實質上提供了進程通信的端點。進程通信之前,雙方首先必須各自創建一個端點,否則是沒有辦法建立聯系並相互通信的。正如打電話之前,雙方必須各自擁有一台電話機一樣。
在網間網內部,每一個Socket用一個半相關描述:(協議,本地地址,本地埠)。
一個完整的Socket有一個本地唯一的Socket號,由操作系統分配。
最重要的是,Socket是面向客戶/伺服器模型而設計的,針對客戶和伺服器程序提供不同的Socket系統調用。客戶隨機申請一個Socket(相當於一個想打電話的人可以在任何一台入網電話上撥號呼叫),系統為之分配一個Socket號;伺服器擁有全局公認的Socket,任何客戶都可以向它發出連接請求和信息請求(相當於一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。
Socket利用客戶/伺服器模式巧妙地解決了進程之間建立通信連接的問題。伺服器Socket半相關為全局所公認非常重要。讀者不妨考慮一下,兩個完全隨機的用戶進程之間如何建立通信?假如通信雙方沒有任何一方的Socket固定,就好比打電話的雙方彼此不知道對方的電話號碼,要通話是不可能的。
② java群聊功能是如何實現的
Java群聊功能可以通過網路編程實現,一般使用Socket和ServerSocket類來完成。具體實現步驟如下:
1. 創建一個伺服器端程序,使用ServerSocket類創建一個ServerSocket對象,並指定監聽的埠號。
2. 創建一個客戶端程序,使用Socket類創建一個Socket對象,並指定連接的伺服器IP地址和埠號。
3. 伺服器端接收客戶端連接後,使用accept()方法獲取到與該客戶端通信的Socket對象。
4. 伺服器端開啟一個新的線程,喚瞎使用該線程與客戶端進行通信,並且將該線程添加到一個線程集合中。
5. 客戶端向伺服器端發送消姿純息時,使用Socket對象的OutputStream將消息發送給伺服器端。
6. 伺服器端從線程集合中獲取每個線程,遍歷並向每個客戶端發送消息,使用Socket對象的OutputStream將消息發送給客戶端。
7. 客戶端使用Socket對象的InputStream讀取伺服器端發送的消息。
8. 當客戶端或伺服器端任意一方關閉連接時,另一方也需要關閉連接。
以上是簡要的Java群聊實現步驟,當然還有其他細節需要考慮,比如消息的格式跡鏈咐、多線程同步等問題,但總體上這些步驟可以幫助你實現Java群聊功能。
③ java編寫多人聊天室中,如何在群聊里@xx,然後這條消息只發送給xx,其他人看不到
私聊功能跟你截屏的這段代碼沒有關系,首先你是多人聊天室,肯定要開連接池來解決線程問題,每個客戶端都有自己對象創建的流,正常大家在公共聊天時,socket伺服器向所有對象的流同一發送消息,當私聊時需要先找到對應對象的流,伺服器單獨向該流發送消息就可以實現私聊功能了。
建議你在創建對象時,將每個對象的昵稱和流存入一個map集合,私聊時通過昵稱來找到對應的流。
④ 急需一個用java 語言寫的聊天程序
客戶端:
package chatroom;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
public class client extends JFrame implements ActionListener,Runnable{
JPanel conn,text,send;
JLabel name,sendto;
JComboBox list;
JButton con,snd,clear;
JTextArea talk;
JTextField who,say;
jscrollPane jsp;
Socket client;
InputStream is;
OutputStream os;
PrintStream ps;
BufferedReader br;
String receive,yousay;
Thread th;
DataInputStream dis;
Double tof;
client()
{
super("聊天室客戶端");
this.setSize(800,600);
this.setResizable(false);
conn=new JPanel();
text=new JPanel();
send=new JPanel();
this.getContentPane().add(conn);
conn.setBounds(0, 0, this.getWidth(),50);
name=new JLabel("姓名:");
who=new JTextField();
con=new JButton("連接");
conn.setLayout(null);
conn.add(name);
name.setBounds(30, 10, 50, 25);
conn.add(who);
who.setBounds(80, 10, 150, 25);
conn.add(con);
con.setBounds(250,10, 60, 25);
this.getContentPane().add(text);
text.setBounds(0,50,this.getWidth(),450);
text.setLayout(new BorderLayout());
jsp=new JScrollPane();
talk=new JTextArea();
jsp.getViewport().setView(talk);
text.add(jsp,"Center");
talk.setLineWrap(true);
this.getContentPane().add(send);
send.setLayout(null);
send.setBounds(0, 480, this.getWidth(), 150);
sendto=new JLabel("發送到:");
snd=new JButton("發送");
list=new JComboBox();
say=new JTextField();
clear=new JButton("清空");
send.add(sendto);
sendto.setBounds(30, 525, 50, 25);
send.add(list);
list.setBounds(100, 525, 75, 25);
send.add(say);
say.setEditable(true);
say.setBounds(200, 525, 300, 25);
send.add(snd);
snd.setBounds(520, 525, 100, 25);
send.add(clear);
clear.setBounds(650, 525, 100, 25);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
con.addActionListener(this);
snd.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("連接"))
{
try
{
client=new Socket(InetAddress.getLocalHost(),55555);
talk.append("連接成功...\n");
con.setText("斷開");
is=client.getInputStream();
os=client.getOutputStream();
th=new Thread(this);
String id=who.getText();
byte b[]=id.getBytes();
DataOutputStream dos=new DataOutputStream(os);
int len=b.length;
dos.writeInt(len);
dos.write(b);
th.start();
}catch(Exception e){talk.append("連接失敗\n"+e.toString()+"0000");}
}
else if(ae.getSource()==snd)
{
if(list.getSelectedItem().toString()=="所有人")
{
yousay="@open"+say.getText();
byte b[]=yousay.getBytes();
DataOutputStream dos=new DataOutputStream(os);
try{
int len=b.length;
dos.writeInt(len);
dos.write(b);
}catch(Exception e)
{
System.out.print(e.toString()+"1111");
}
}
else
{
yousay="@whisper"+say.getText();
byte b[]=yousay.getBytes();
byte w[]=list.getSelectedItem().toString().getBytes();
DataOutputStream dos=new DataOutputStream(os);
try{
int len=b.length;
int wlen=w.length;
dos.writeInt(len); //內容
dos.write(b);
dos.writeInt(wlen); //發送對象
dos.write(w);
}catch(Exception e)
{
System.out.print(e.toString()+"AAAA");
}
}
}
else if(ae.getActionCommand().equals("斷開"))
{
try
{
client.close();
talk.append("連接已斷開\n");
con.setText("連接");
}catch(Exception e){System.out.println(e.toString()+"2222");}
}
}
public void run()
{
while(true)
{
try
{
dis=new DataInputStream(is);
tof=dis.readDouble();
if(tof==1.1)
{
dis=new DataInputStream(is);
int number;
list.removeAllItems();
list.addItem("所有人");
number=dis.readInt();
for(int i=0;i<number;i++)
{
int len=dis.readInt();
byte b[]=new byte[len];
dis.read(b);
String name=new String(b);
list.addItem(name);
}
}
else if(tof==2.2)
{
try
{
dis=new DataInputStream(is);
int len=dis.readInt();
byte b[]=new byte[len];
dis.read(b);
receive=new String(b);
talk.append(receive+"\n");
}catch(Exception e){JOptionPane.showMessageDialog(this, "連接已斷開","消息",JOptionPane.INFORMATION_MESSAGE);break;}
}
}catch(Exception e){JOptionPane.showMessageDialog(this, "連接已斷開","消息",JOptionPane.INFORMATION_MESSAGE);break;}
}
}
public static void main(String[] args) {
client cl=new client();
}
}
服務端:
package chatroom;
import java.awt.*;
import javax.swing.*;
import java.net.*;
import java.util.Vector;
import java.io.*;
public class server extends JFrame implements Runnable{
JPanel jp1;
JTextArea jta;
JScrollPane jsp;
Socket socket=null;
ServerSocket server;
InputStream is;
OutputStream os;
static int i=0,login;
int no;
static String s="";
Thread sr;
Thread th[]=new Thread[20];
static Vector ol=new Vector();
static public byte w[]=null;
static String from=""; //人名
static String to="";
static String fromtext=""; //內容
static String totext="";
server()
{
super("聊天室服務端");
this.getContentPane().setLayout(new GridLayout(1,1));
this.setSize(400,300);
jp1=new JPanel();
jta=new JTextArea();
jsp=new JScrollPane();
this.getContentPane().add(jp1);
jp1.setLayout(new GridLayout(1,1));
jsp.getViewport().setView(jta);
jp1.add(jsp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
server sr=new server();
sr.sr=new Thread(sr);
sr.sr.start();
sendtoall sta=new sendtoall();
returnfrom rf=new returnfrom(sr);
returnto rt=new returnto(sr);
sta.start();
rf.start();
rt.start();
}
public void run()
{
try
{
server=new ServerSocket(55555);
while(true)
{
socket=server.accept();
is=socket.getInputStream();
DataInputStream dis=new DataInputStream(is);
int len=dis.readInt();
byte b[]=new byte[len];
dis.read(b);
String id=new String(b);
record v=new record(id,socket);
ol.addElement(v);
for (int i=0;i<ol.size();i++)
{
if (ol.elementAt(i).equals(v))
{
no=i;
}
}
login=1;
s=id+"已來到聊天室!";
th[no]=new Thread(new receive(this,no));
th[no].start();
}
}catch(Exception e){System.out.println(e.toString()+"aaaa");}
}
}
class receive implements Runnable
{
InputStream is;
OutputStream os;
server sr;
Socket sk;
int i;
String name;
String ip;
receive(server sr,int i)
{
this.sr=sr;
this.i=i;
sk=((record)sr.ol.elementAt(i)).ip;
name=((record)sr.ol.elementAt(i)).name;
ip=((record)sr.ol.elementAt(i)).ip.getInetAddress().toString();
}
public void run()
{
while(true)
{
try
{
is=sk.getInputStream();
DataInputStream dis=new DataInputStream(is);
int len=dis.readInt();
byte b[]=new byte[len];
dis.read(b);
String abc=new String(b);
sr.jta.append(abc);
if(abc.substring(0,5).equals("@open"))
{
server.s=name+"["+ip.substring(1, ip.length())+"]"+"說:"+abc.substring(5,abc.length());
sr.jta.append(server.s+"\n");
}
else if(abc.substring(0,8).equals("@whisper"))
{
int wlen=dis.readInt();
sr.w=new byte[wlen];
dis.read(sr.w);
server.to=new String(sr.w);
server.from=((record)sr.ol.elementAt(i)).name;
String ip=((record)sr.ol.elementAt(i)).ip.getInetAddress().toString();
// server.s=server.from+"對"+server.to+"["+ip.substring(1, ip.length())+"]"+"悄悄地說:"+abc.substring(8,abc.length());
server.fromtext="你對"+server.to+"["+ip.substring(1, ip.length())+"]"+"悄悄地說:"+abc.substring(8,abc.length());
server.totext=server.from+"["+ip.substring(1, ip.length())+"]"+"對你悄悄地說:"+abc.substring(8,abc.length());
sr.jta.append(server.s+"\n");
}
}catch(Exception e)
{
try
{
DataOutputStream dos=new DataOutputStream(os);
server.ol.removeElementAt(i);
server.s=name+"已離開聊天室.";
server.login=1;
break;
}catch(Exception f){}
}
}
}
}
class sendtoall extends Thread
{
int len,number;
byte b[];
server sr;
Socket st;
OutputStream os;
DataOutputStream dos;
public void run()
{
while(true)
{
try
{
if(server.login==1)
{
number=0;
number=server.ol.size();
dos=new DataOutputStream(os);
for(int i=0;i<server.ol.size();i++)
{
st=((record)sr.ol.elementAt(i)).ip;
os=st.getOutputStream();
dos=new DataOutputStream(os);
dos.writeDouble(1.1);
dos.writeInt(number);
for (int j=0;j<number;j++)
{
String name=((record)sr.ol.elementAt(j)).name;
byte b[]=name.getBytes();
int len=b.length;
dos.writeInt(len);
dos.write(b);
}
}
server.login=0;
}
else if(!server.s.equals("")&&sr.ol.size()>0)
{
b=server.s.getBytes(); //String類型中 漢字佔一個位元組,但是byte類型中,漢字占兩個位元組
len=b.length;
//len=server.s.length();
//b=new byte[len];
//b=server.s.getBytes();
for(int i=0;i<server.ol.size();i++)
{
st=((record)sr.ol.elementAt(i)).ip;
os=st.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeDouble(2.2);
dos.writeInt(len);
dos.write(b);
}
server.s="";
}
}catch(Exception e){System.out.println(e.toString()+"sdasd");}
}
}
}
class returnfrom extends Thread
{
int len,wlen;
byte b[];
byte w[];
server sr;
Socket st;
OutputStream os;
DataOutputStream dos;
//String from="",to="";
returnfrom(server sr)
{
this.sr=sr;
}
public void run()
{
while(true)
{
if(!server.fromtext.equals(""))
{
b=server.fromtext.getBytes();
len=b.length;
sr.jta.append(sr.fromtext);
try
{
for(int i=0;i<server.ol.size();i++)
{
if(((record)sr.ol.elementAt(i)).name.equals(server.from))
{
st=((record)sr.ol.elementAt(i)).ip;
os=st.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeDouble(2.2);
dos.writeInt(len);
dos.write(b);
}
}
}catch(Exception e){System.out.println(e.toString()+"wwww");}
server.fromtext="";
server.from="";
}
}
}
}
class returnto extends Thread
{
int len,wlen;
byte b[];
byte w[];
server sr;
Socket st;
OutputStream os;
DataOutputStream dos;
//String from="",to="";
returnto (server sr)
{
this.sr=sr;
}
public void run()
{
while(true)
{
if(!server.totext.equals(""))
{
w=server.totext.getBytes();
wlen=w.length;
try
{
for(int i=0;i<server.ol.size();i++)
{
if(((record)sr.ol.elementAt(i)).name.equals(server.to))
{
st=((record)sr.ol.elementAt(i)).ip;
os=st.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeDouble(2.2);
dos.writeInt(wlen);
dos.write(w);
}
}
}catch(Exception e){System.out.println(e.toString()+"wwww");}
server.totext="";
server.to="";
}
}
}
}
class record
{
String name;
Socket ip;
record(String id,Socket socket)
{
name=id;
ip=socket;
}
}
以前學習java時寫的,是個在線聊天室只有群聊,私聊,上下線提示,搞不好裡面還有錯誤- -其他功能自己看著加吧,你要的功能實在是很好很強大.
⑤ 用Java實現一個人和幾個不同的人私聊,用Socket實現
package API_Day09;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 控制台聊天程序
* 客戶端應用程序
* @author Jacob
*
*/
public class chatClient
{
//客戶端用於與服務端連接的Socket
private Socket clientSocket;
/**
* 構造方法,客戶端初始化
*/
public chatClient()
{
try
{
/*
* socket(String host, int port)
* 地址: IP地址,用來定位網路上的計算機
* 埠: 用來找到遠端計算機上用來連接的服務端應用程序
*/
clientSocket = new Socket("localhost",12580);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* 客戶端昵稱驗證方法
* @param 為Scanner
*/
private void inputNickName(Scanner scan) throws Exception
{
String nickName = null;
//創建輸出流
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(clientSocket.getOutputStream(),
"UTF-8"),true);
//創建輸入流
BufferedReader br = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream(),"UTF-8"));
while(true)
{
System.out.println("請創建您的昵稱:");
nickName = scan.nextLine();
if (nickName.trim().equals(""))
{
System.out.println("昵稱不得為空");
}
else
{
pw.println(nickName);
String pass = br.readLine();
if(pass!=null&&!pass.equals("OK"))
{
System.out.println("昵稱已經被佔用,請更換!");
}
else
{
System.out.println("你好!"+nickName+"可以開始聊天了");
break;
}
}
}
}
/*
* 客戶端啟動的方法
*/
public void start()
{
try
{
/*
* 創建Scanner,讀取用戶輸入內容
* 目的是設置客戶端的昵稱
*/
Scanner scanner = new Scanner(System.in);
inputNickName(scanner);
/*
* 將用於接收伺服器端發送過來的信息的線程啟動
*/
Runnable run = new GetServerMsgHandler();
Thread t = new Thread(run);
t.start();
/*
* 建立輸出流,給服務端發信息
*/
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw,true);
while(true)
{
pw.println(scanner.nextLine());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(clientSocket !=null)
{
try
{
clientSocket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
/**
* 該線程體用來循環讀取服務端發送過來的信息
* 並輸出到客戶端的控制台
* @param args
*/
class GetServerMsgHandler implements Runnable
{
@Override
public void run()
{
try
{
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String msgString = null;
while((msgString = br.readLine())!= null)
{
System.out.println("服務端提示:"+ msgString);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
chatClient client = new chatClient();
client.start();
}
}
package API_Day09;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 控制台聊天程序
* 服務端應用程序
* @author Jacob
*
*/
public class chatServer
{
/**
* ServerSocket 是運行在服務端的Socket
* 用來監聽埠,等待客戶端的連接,
* 一旦連接成功就會返回與該客戶端通信的Socket
*/
private ServerSocket serverSocket;
/**
* 創建線程池來管理客戶端的連接線程
* 避免系統資源過度浪費
*/
private ExecutorService threadPool;
/**
* 該屬性用來存放客戶端之間私聊的信息
*/
private Map<String,PrintWriter> allOut;
/**
* 構造方法,服務端初始化
*/
public chatServer()
{
try
{
/*
* 創建ServerSocket,並申請服務埠
* 將來客戶端就是通過該埠連接服務端程序的
*/
serverSocket = new ServerSocket(12580);
/*
* 初始化Map集合,存放客戶端信息
*/
allOut = new HashMap<String, PrintWriter>();
/*
* 初始化線程池,設置線程的數量
*/
threadPool = Executors.newFixedThreadPool(10);
/*
* 初始化用來存放客戶端輸出流的集合,
* 每當一個客戶端連接,就會將該客戶端的輸出流存入該集合;
* 每當一個客戶端斷開連接,就會將集合中該客戶端的輸出流刪除;
* 每當轉發一條信息,就要遍歷集合中的所有輸出流(元素)
* 因此轉發的頻率高於客戶端登入登出的頻率,
* 還是應該使用ArrayList來存儲元素,僅限群聊,私聊不行
* allOut = new ArrayList<PrintWriter>();
*/
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*
* 將客戶端的信息以Map形式存入集合中
*/
private void addOut(String key,PrintWriter value)
{
synchronized(this)
{
allOut.put(key, value);
}
}
/*
* 將給定的輸出流從共享集合中刪除
* 參數為客戶端nickName,作為Map的key鍵
*/
private synchronized void removeOut(String key)
{
allOut.remove(key);
System.out.println("當前在線人數為:"+ allOut.size());
}
/*
* 將給定的消息轉發給所有客戶端
*/
private synchronized void sendMsgToAll(String message)
{
for(PrintWriter out: allOut.values())
{
out.println(message);
System.out.println("當前在線人數為:"+ allOut.size());
}
}
/*
* 將給定的消息轉發給私聊的客戶端
*/
private synchronized void sendMsgToPrivate(String nickname,String message)
{
PrintWriter pw = allOut.get(nickname); //將對應客戶端的聊天信息取出作為私聊內容發送出去
if(pw!=null)
{
pw.println(message);
System.out.println("當前在線私聊人數為:"+ allOut.size());
}
}
/**
* 服務端啟動的方法
*/
public void start()
{
try
{
while(true)
{
/*
* 監聽10086埠
*/
System.out.println("等待客戶端連接... ... ");
/*
* Socket accept() 這是一個阻塞方法,會一直在10086埠進行監聽
* 直到一個客戶端連接上,此時該方法會將與這個客戶端進行通信的Socket返回
*/
Socket socket = serverSocket.accept();
System.out.println("客戶端連接成功! ");
/*
* 啟動一個線程,由線程來處理客戶端的請求,這樣可以再次監聽
* 下一個客戶端的連接了
*/
Runnable run = new GetClientMsgHandler(socket);
threadPool.execute(run); //通過線程池來分配線程
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 該線程體用來處理給定的某一個客戶端的消息,循環接收客戶端發送
* 的每一個字元串,並輸出到控制台
* @author Jacob
*
*/
class GetClientMsgHandler implements Runnable
{
/*
* 該屬性是當前線程處理的具體的客戶端的Socket
* @see java.lang.Runnable#run()
*/
private Socket socket;
/*
* 獲取客戶端的地址信息
* private String hostIP;
*/
/*
* 獲取客戶端的昵稱
*/
private String nickName;
/*
* 創建構造方法
*/
public GetClientMsgHandler(Socket socket)
{
this.socket = socket;
/*
* 獲取遠端客戶的Ip地址信息
* 保存客戶端的IP地址字元串
* InetAddress address = socket.getInetAddress();
* hostIP = address.getHostAddress();
*/
}
/*
* 創建內部類來獲取昵稱
*/
private String getNickName() throws Exception
{
try
{
//服務端的輸入流讀取客戶端發送來的昵稱輸出流
InputStream iin = socket.getInputStream();
InputStreamReader isr =
new InputStreamReader(iin,"UTF-8");
BufferedReader bReader = new BufferedReader(isr);
//服務端將昵稱驗證結果通過自身的輸出流發送給客戶端
OutputStream out = socket.getOutputStream();
OutputStreamWriter iosw =
new OutputStreamWriter(out,"UTF-8");
PrintWriter ipw = new PrintWriter(iosw,true);
//讀取客戶端發來的昵稱
String nameString = bReader.readLine();
while(true)
{
if(nameString.trim().length()==0)
{
ipw.println("FAIL");
}
if(allOut.containsKey(nameString))
{
ipw.println("FAIL");
}
else
{
ipw.println("OK");
return nameString;
}
nameString = bReader.readLine();
}
}
catch(Exception e)
{
throw e;
}
}
@Override
public void run()
{
PrintWriter pw = null;
try
{
/*
* 通過客戶端的Socket獲取客戶端的輸出流
* 用來將消息發送給客戶端
*/
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
pw = new PrintWriter(osw,true);
/*
* 將客戶昵稱和其所說的話作為元素存入共享集合HashMap中
*/
nickName = getNickName();
addOut(nickName, pw);
Thread.sleep(100);
/*
* 服務端通知所有客戶端,某用戶登錄
*/
sendMsgToAll("[系統通知]:歡迎**"+nickName+"**登陸聊天室!");
/*
* 通過客戶端的Socket獲取輸入流
* 讀取客戶端發送來的信息
*/
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String msgString = null;
while((msgString = br.readLine())!=null)
{
//驗證是否是私聊
if(msgString.startsWith("@"))
{
/*
* 私聊格式:@昵稱:內容
*/
int index = msgString.indexOf(":");
if(index >=0)
{
//獲取昵稱
String name = msgString.substring(1,index);
String info = msgString.substring(index+1,msgString.length());
info = nickName + "對你說:"+ info;
//將私聊信息發送出去
sendMsgToPrivate(name, info);
//服務端不在廣播私聊的信息
continue;
}
}
/*
* 遍歷所有輸出流,將該客戶端發送的信息轉發給所有客戶端
*/
System.out.println(nickName+"說:"+ msgString);
sendMsgToAll(nickName+"說:"+ msgString);
}
}
catch (Exception e)
{
/*
* 因為Win系統用戶的客戶端斷開連接後,br.readLine()方法讀取
* 不到信息就會拋出異常,而Linux系統會持續發送null;
* 因此這里就不在將捕獲的異常拋出了。
*/
}
finally
{
/*
* 當執行到此處時,說明客戶端已經與服務端斷開連接
* 則將該客戶端存在共享集合中的輸出流刪除
*/
removeOut(nickName);
/*
* 通知所有客戶端,某某客戶已經下線
*/
sendMsgToAll("[系統通知]:"+nickName + "已經下線了。");
/*
* 關閉socket,則通過Socket獲取的輸入輸出流也一同關閉了
*/
if(socket!=null)
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args)
{
chatServer server = new chatServer();
server.start();
}
}
我的作業,供你參考
⑥ 求一個用java socket編寫的聊天室程序,能運行的附帶源碼,有客戶端和伺服器端
要多強大的版本。
1.1草圖界面,主要實現功能。
1.2 +群聊。
1.3+上線提醒。
1.4+界面優化,仿照版QQ2012,+好友上線頭像變亮權。
1.5+視屏,傳文件,表情,裝口震動,截圖。
我先把1.1的發給你吧。。。
2013年5月31日 13:08:36已發。。
⑦ 用java編寫一個多人聊天室可以 實現私聊,群聊,文件傳送的功能
你這就整麻煩了,如果你只是想實現這些功能,不要求速度也不要存儲空間,也不要求有界面那還比較簡單,實體類序列化所有傳送對象,在socket類中用object流直接傳和接收所有的東西(包括聊天信息和文件)再用多線程實現群聊.大概兩三天可以搞定.
如果你像做得類似於QQ一樣,那就不是幾天的事情了
⑧ java開發聊天功能用什麼技術
Java開發聊天功能可以使用Socket和ServerSocket技術來實現。
在這種情況下,伺服器端需要創建一個ServerSocket對象來監聽客戶端的連接請求槐伍。當有新的連接請求到達時,伺服器會創建一個鉛敏或新的Socket對象來與客戶端進行通信,並將該Socket對象加入到線程池中。通過這種方式,伺服器可拿御以同時處理多個客戶端的連接請求和消息交互。
客戶端需要創建一個Socket對象,並指定伺服器端的IP地址和埠號來連接伺服器。連接成功後,客戶端可以向伺服器發送消息,也可以接收來自伺服器的消息。當客戶端退出聊天室時,需要關閉Socket連接,並通知伺服器該客戶端已經離開。
在實際開發中,還需要考慮到消息的編碼和解碼、異常處理、線程安全等問題。可以使用現成的開源框架如Netty、Spring Boot等來簡化聊天功能的開發。同時,還需要進行充分的測試和優化,以提高聊天功能的性能和用戶體驗。
⑨ java實現聊天室是怎麼做到的
Java 實現聊天室可以分為以下幾個步驟:
建立伺服器端
首先需要建立一個伺服器端,負責接收客戶端的連接請求並處理客戶端發送過來的消息。
建立客戶端
然後需要建立冊陸客戶端,客戶端通過正姿畢網路連接到伺服器端,並向伺服器端發送消息。
實現通信協議
為了實現聊天室功能,需要定義一個通信協議,規定客戶端和伺服器端之間的通信格式,例如消息的頭部和內容等。
實現多線程處理
聊天室通常會有多個用戶同時在線,因此需要使用多線程舉芹來處理多個客戶端的連接請求和消息傳遞。
實現GUI界面(可選)
為了方便用戶使用,可以實現一個GUI界面,讓用戶可以方便地發送和接收消息。
以下是一個簡單的 Java 聊天室的代碼示例:
java
Copy code
// 伺服器端代碼
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket socket = serverSocket.accept();
new Thread(new ServerThread(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ServerThread implements Runnable {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
public ServerThread(Socket socket) {
this.socket = socket;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
String msg;
while ((msg = reader.readLine()) != null) {
// 處理客戶端發送過來的消息
System.out.println("接收到消息:" + msg);
// 將消息發送給所有客戶端
for (Socket s : ServerThreadList.getList()) {
if (s != socket) {
PrintWriter w = new PrintWriter(s.getOutputStream());
w.println(msg);
w.flush();
}
}
}
// 關閉連接
socket.close();
ServerThreadList.removeThread(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ServerThreadList {
private static List
list = new ArrayList<>();
public static void addThread(ServerThread thread) {
list.add(thread);
}
public static void removeThread(ServerThread thread) {
list.remove(thread);
}
public static List
getList() {
return list;
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
new Thread(new ClientThread(socket)).start();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while (true) {
String msg = reader.readLine();
writer.println(msg);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientThread implements Runnable {
private Socket socket;
private BufferedReader reader;
public ClientThread(Socket socket) {
this.socket = socket;
try {
reader
⑩ java聊天工具提問
你應該用
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bis來讀,bos來寫,這是基於位元組型的數據流,數據收到以後,都存放在位元組數組中去,再按你的格式拆裝起來。不管是string還是int還是boolean還是圖片、聲音謹鋒或Object都可以.我的程序就是這樣做的。消敏有空看看我的網路 空 間。
但要注意,位元組流在tcp/ip連接中,可能會拿晌枝存在粘包的問題。這需要你自己設計數據包的格式,
比如:你的收包程序一起在收,每收一次就檢查是否收到結束標志,收到了就表示此次數據接收完成。否則,就繼續收,直到找到結束標志。