程序的基础

来源:互联网 发布:sql注入测试网站 编辑:程序博客网 时间:2024/06/09 13:07

今天写了个聊天室





import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;


public class ChatFrame extends JFrame {

private JPanel upPanel;
private JPanel downPanel;

final JTextArea sendJTa;
final JTextArea receiveJTa;


public ChatFrame() {
setTitle("聊天窗口");
setSize(600, 480);
upPanel = new JPanel();
downPanel = new JPanel();
sendJTa = new JTextArea();
sendJTa.setPreferredSize(new Dimension(600, 200));
sendJTa.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String msg = sendJTa.getText();
sendJTa.setText("");
System.out.println("按下了回车键");
sendMsg(msg);
}
}
});
receiveJTa = new JTextArea();
receiveJTa.setPreferredSize(new Dimension(600, 200));
upPanel.add(receiveJTa);
downPanel.add(sendJTa);
this.getContentPane().add(upPanel, BorderLayout.NORTH);
this.getContentPane().add(downPanel, BorderLayout.SOUTH);

new Thread(new Runnable() { // 服务端是运行在子线程中的
public void run() {
initServer();
}
}).start(); 

this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
close();  // 关闭服务端Socket
System.exit(0);
}

});
setVisible(true);
}

public void close() {
isRunning = false;
sendMsg("close"); // 1.关闭服务器的时候,需要向服务器发送关闭信号,让服务器不要再继续等待连接

// try {
// ss.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}

/*
*每个窗口程序,有一个监听线程 
*/

ServerSocket ss = null;
// 这个关键字的作用 ,是标记这个变量是易变,每次修改后,会反应到所有线程
volatile boolean isRunning = true;
public void initServer() { // 只是接收
try {
ss = new ServerSocket(8899);
while (isRunning) { // 判断程序的运行状态
Socket s = ss.accept(); // 服务端的线程会阻塞在此处
// 2.服务器子线程收到关闭信号之后,最后一次收到消息,并关闭自己的循环逻辑
DataInputStream dis = new DataInputStream(s.getInputStream()); // 连接上来之后,先读取一下客户端的内容
String recevieStr = dis.readUTF();
receiveJTa.append(recevieStr + "\n");
String backStr = "我收到消息,反馈信息";
DataOutputStream dos = new DataOutputStream(s.getOutputStream());  
dos.writeUTF(backStr);
}
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}

// 发送
public void sendMsg(String msg) {
try {
Socket s = new Socket("127.0.0.1", 8899);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(msg);
DataInputStream dis = new DataInputStream(s.getInputStream());
String returnInfo = dis.readUTF();
System.out.println("服务端:" + returnInfo);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}


public static void main(String[] args) {
// 一般用这种方式启动Swing程序,避免Swing的单线程模型引起的问题
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ChatFrame();
}
});



}

这里我就只贴上服务端了

这个程序教会了我很多基础的东西比如说一个类中的public void 方法可以是相互调用的如果起初自己能想到一定会为自己节省下来很多时间其次嘛

有一个按键的监听它与事件的监听是不一样的不过有很多相似之处

其次就是很多奇怪的写法很多时候我们会在网上看到一些程序中奇怪的写法但是不必精慌仔细观察其实都是可以看到里面的细节都是一些程序的简写可以为我们的的程序节省下来很多时间详细的细节都可以以参考上面的程序注释。。。。。。。。。。。。。

0 0