|
//使用了多线程,支持多用户聊天
//聊天室功能极缺,没有登陆功能,直接聊天,用户名是自动生成的
//喜欢网络程序设计的同学可以参考。
package tcpserver;
import javax.swing.UIManager;
import java.awt.*;
/**
* <p>Title: no</p>
* <p>Description: This a Java builder program</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: home</p>
* @author syd168
* @version 1.0
*/
public class Application1 {
private boolean packFrame = false;
//Construct the application
public Application1() {
Frame1 frame = new Frame1();
//Validate frames that have preset sizes
//Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
}
//Main method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new Application1();
}
}
===============================================
package tcpserver;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
/**
* <p>Title: no</p>
* <p>Description: This a Java builder program</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: home</p>
* @author syd168
* @version 1.0
*/
public class Frame1 extends JFrame implements Runnable{
private JPanel contentPane;
private TextArea textArea1 = new TextArea();
private Label label1 = new Label();
private JTextField textField1 = new JTextField();
private JButton button1 = new JButton();
private JButton button2 = new JButton();
ServerSocket server = null;
BufferedReader in = null;
PrintWriter out = null;
InetAddress myServer=null;
JLabel serverIP = new JLabel();
JLabel port = new JLabel();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel l1=new DefaultListModel();
JList jList1 = new JList();
Object users[]=new Object[1000];//user,IP,socket,toUser,message
static int userCount=0;
//Construct the frame
public Frame1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try { jbInit(); } catch(Exception e) { e.printStackTrace(); }
}
//Component initialization
private void jbInit() throws Exception {
serverIP.setText("服务器:"+InetAddress.getLocalHost().getHostAddress());
serverIP.setBounds(new Rectangle(32, 244, 133, 23));
//setIconImage(Toolkit.getDefaultToolkit().createImage(Frame1.class.getResource("[Your Icon]")));
contentPane = (JPanel) this.getContentPane();
textArea1.setBackground(Color.yellow);
textArea1.setEditable(false);
textArea1.setFont(new java.awt.Font("Dialog", Font.PLAIN, 14));
textArea1.setBounds(new Rectangle(5, 7, 389, 190));
contentPane.setLayout(null);
this.setSize(new Dimension(500, 320));
this.setTitle("服务器端");
label1.setFont(new java.awt.Font("Dialog", Font.PLAIN, 12));
label1.setText("消息:");
label1.setBounds(new Rectangle(27, 207, 35, 26));
textField1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(KeyEvent e) {
textField1_keyPressed(e);
}
});
button1.setBounds(new Rectangle(319, 207, 58, 26));
button1.setEnabled(false);
button1.setFont(new java.awt.Font("Dialog", Font.PLAIN, 12));
button1.setText("发送");
button1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
button1_actionPerformed(e);
}
});
button2.setBounds(new Rectangle(287, 241, 97, 30));
button2.setFont(new java.awt.Font("Dialog", Font.PLAIN, 12));
button2.setText("退出");
button2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
button2_actionPerformed(e);
}
});
serverIP.setFont(new java.awt.Font("Dialog", Font.BOLD, 14));
serverIP.setForeground(Color.blue);
port.setFont(new java.awt.Font("Dialog", Font.BOLD, 14));
port.setForeground(Color.blue);
port.setBounds(new Rectangle(162, 245, 0, 0));
textField1.setBounds(new Rectangle(62, 208, 254, 26));
jScrollPane1.setBounds(new Rectangle(403, 8, 81, 262));
jScrollPane1.getViewport().add(jList1);
contentPane.add(textArea1, null);
contentPane.add(button2, null);
contentPane.add(button1, null);
contentPane.add(serverIP, null);
contentPane.add(port, null);
contentPane.add(label1, null);
contentPane.add(textField1, null);
contentPane.add(jScrollPane1, null);
jList1.setModel(l1);
Thread thread = new Thread(this);
thread.start();
}
//Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
//添加代码
try{
out.println("服务器断开!");
out.flush();
}catch(Exception ex){}
finally{
System.exit(0);
}
}
}
void button1_actionPerformed(ActionEvent e) {
out.println(textField1.getText());
out.flush();
textArea1.append("服务器消息:"+textField1.getText()+"\n");
}
void button2_actionPerformed(ActionEvent e) {
try{
out.println("服务器断开!");
out.flush();
}catch(Exception e2){}
finally{
System.exit(0);
}
}
void textField1_keyPressed(KeyEvent e) {
int j=e.getKeyCode();
if(j==e.VK_ENTER){
out.println(textField1.getText());
out.flush();
textArea1.append("服务器消息:"+textField1.getText()+"\n");
textField1.setText("");
}
}
public void run() {
try{
//在端口5438上注册服务
server = new ServerSocket(8000);
port.setText(String.valueOf("端口:"+server.getLocalPort()));
Socket socket;
while(true){
socket = server.accept();//这里一直等待,如果连接成功,则创建了本机通信的套接层
if (socket!= null){//新用户连接成功,添加客户到数组和列表
textArea1.append("来自"+socket.getInetAddress().getHostAddress()+"的用户,端口:"+String.valueOf(socket.getPort())+"\n");
users[userCount]=socket;//toUser;
l1.addElement("user"+userCount);
Receiver r = new Receiver(socket,userCount);//创建接收线程
Thread t = new Thread(r);//创建接收线程
t.start();
userCount++;
}
}
} catch(Exception e){ textArea1.append(e.toString()+"\n");
}
}
private class Receiver implements Runnable{
Socket socket;
int user;
Receiver(Socket socket,int user){
this.socket=socket;
this.user=user;
}
public void run(){
BufferedReader in = null;
PrintWriter out = null;
String s1 = null;
int userNo;
try{
out=new PrintWriter(socket.getOutputStream());//通知所有客户新用户的到来
out.println("user"+user);//让对方知道自己的名字
out.flush();
for(int j=0;j<userCount;j++){//对所有的用户发送
if(users[j]==null)continue;
out=new PrintWriter(((Socket)users[j]).getOutputStream());//通知所有客户新用户的到来
out.println("Clear users!"); //让对方刷新自己的列表
out.flush();
for(int k=0;k<userCount;k++){
out.println("user" + k); //让大家知道自己的名字
out.flush();
}
}
in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
s1 = in.readLine();
while(s1!= "大家尽情聊,再见!"){//必须是死循环方式接收,否则丢失数据!
int temp=s1.indexOf("对");
int temp1=s1.indexOf("说");
String tempS=s1.substring(temp+1,temp1);
if(tempS.equals("大家")){
for(int j=0;j<userCount;j++){//对所有的用户发送
if(users[j]==null)continue;
out=new PrintWriter(((Socket)users[j]).getOutputStream());//通知所有客户新用户的到来
out.println(s1); //让对方刷新自己的列表
out.flush();
}
}
else{
try{
userNo = Integer.parseInt(tempS.substring(4));
out=new PrintWriter(((Socket)users[userNo]).getOutputStream());//通知所有客户新用户的到来
out.println(s1); //发送给指定的用户
out.flush();
}catch(Exception e){}
}
//服务器端列出
textArea1.append(s1+":\n");
s1 = in.readLine();//接收当前缓存数据
}
in.close();
out.close();
socket.close();
}catch(Exception e){}
}
}
} |
|