java 聊天程序
2015-07-21 08:34
501 查看
package cn.apr.chart;
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer {
/**
* @param args
* m_threads是一个Vector静态变量,维护所有Server方的ServerThread对象,
* 通过该变量能向所有加入聊天室的聊天者ChatApplet广播信息,撤销退出的聊天者。
* 聊天服务者ChatServer的主方法。该方法监听聊天者Chat Applet的请求, 并为新连接的聊天者创建一个服务线程。
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket socket = null;
Vector m_threads = new Vector();
System.out.println("listen...");
try {
// 设置ServerSocket监听端口号为5555,这个数字必须和程序聊天者ChatApplet中的port参数一致
socket = new ServerSocket(5555);
} catch (Exception e) {
System.out.println("new ServerSocket() failed!");
return;
}
try {
int nid = 0;
while (true) {
// 监听是否有新聊天者Chat Applet连接到聊天Server,
// 线程运行到该语句会封锁,直到有新的连接产生
Socket s = socket.accept();
System.out.println("accepted");
// 创建一个新的ServerThread
ServerThread st = new ServerThread(s, m_threads);
// 为该线程设置一个ID号
st.setID(nid++);
// 将线程加入到m_threads Vector中
m_threads.addElement(st);
// 启动服务线程
new Thread(st).start();
// 通知所有ChatApplet有一个新的网友加入
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st1 = (ServerThread) m_threads.elementAt(i);
st1.write("<#>welcome" + st.getID() + "to enter chatroom!");
}
System.out.println("Listen again...");
}
} catch (Exception e) {
System.out.println("Server is down...");
}
}
}
// 监听线程,监听对应的Chat Applet是否有信息传来
class ServerThread implements Runnable {
Vector m_threads;
Socket m_socket = null;
DataInputStream m_in = null;
DataOutputStream m_out = null;
int m_nid;
// 初始化线程
public ServerThread(Socket s, Vector threads) {
m_socket = s;
m_threads = threads;
try {
// 构造数据输入、输出流对象
m_in = new DataInputStream(m_socket.getInputStream());
m_out = new DataOutputStream(m_socket.getOutputStream());
} catch (Exception e) {
}
}
public void run() // 线程的执行体
{
System.out.println("thread is running");
try {
while (true) {
// 监听对应的ChatApplet是否传来消息
// 线程封锁在m_in.readUTF()中,直到有信息传来才返回
String s = m_in.readUTF();
if (s == null)
break;
// 如果Chat Applet传来的信息为“leave”,则通知所有其他的ChatApplet自己推出了
if (s.trim().equals("leave"))
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st = (ServerThread) m_threads.elementAt(i);
st.write("***" + getID() + "leave..." + "***");
}
else
// 向所有ChatApplet广播该消息
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st = (ServerThread) m_threads.elementAt(i);
st.write("<" + getID() + ">" + s);
}
} // while(true)
} catch (Exception e) {
e.printStackTrace();
}
// 从m_threads Vector中删除该线程,表示该线程已经离开聊天室
m_threads.removeElement(this);
System.out.println("remove element!");
try {
m_socket.close();
} catch (Exception e) {
}
}
// 将msg送回对应的Applet
public void write(String msg) {
synchronized (msg) {
try {
m_out.writeUTF(msg);
} catch (IOException e) {
}
}
}
public int getID() // 获得该线程的ID
{
return m_nid;
}
public void setID(int nid) // 设置线程的ID
{
m_nid = nid;
}
}
//////////////
package cn.apr.chart;
import java.awt.*;
import java.applet.*;
import java.io.*;
import java.net.*;
//继承Applet,实现Runnable
public class ChatApplet1 extends Applet implements Runnable {
TextArea m_textarea; // 接受消息显示窗口
TextField m_textfield; // 发送消息输入窗口
DataInputStream m_in; // 消息输入流
DataOutputStream m_out; // 消息输出流
/**
* @param args
* ChatApplet的初始化方法
*/
public void init() {
// 创建窗口
setLayout(null);
setSize(426, 266);
m_textarea = new TextArea(10, 10);
m_textfield = new TextField();
m_in = null;
m_out = null;
// 初始化Appleton,并连接到聊天服务者
try {
// 获取applet的URL,即通过服务器地址
URL url = getCodeBase();
// 获取服务器IP地址
InetAddress inetaddr = InetAddress.getByName(url.getHost());
Socket m_socket;
// 屏幕显示服务器IP地址、通信协议
System.out.println("Server:" + inetaddr + "" + url.getHost() + ""
+ url.getProtocol());
// 创建与服务器IP地址连接的套接口,5555是聊天服务器套接口端口
m_socket = new Socket(inetaddr, 5555);
// 在套接口上建立输入流
m_in = new DataInputStream(m_socket.getInputStream());
// 在套接口上建立输出流
m_out = new DataOutputStream(m_socket.getOutputStream());
} catch (Exception e) {
System.out.println("Error:" + e);
}
setLayout(new BorderLayout());
add("Center", m_textarea);
add("South", m_textfield);
m_textarea.setEditable(false);
// 启动监听线程
new Thread(this).start();
}
// 当聊天者在消息输入窗口键入回车后,读取字符串,发送给聊天服务者。
public boolean handleEvent(Event event) {
String b = m_textfield.getText();
if ((event.target == m_textfield) && (event.id == Event.ACTION_EVENT)) {
m_textfield.setText("");
// 将聊天者输入的消息发送给ChatServer
try {
m_out.writeUTF(b); // 向聊天服务者发送一个UFT格式字符串
} catch (IOException e) {
}
return true;
} else
return super.handleEvent(event);
}
// 聊天者监听对应的服务线程,在读取对应服务线程传来的消息,并显示在通信显示窗口中
public void run() {
try {
while (true) {
// 聊天者监听对应服务线程发来的消息,它将封锁在该语句中,直到消息到来
String s = m_in.readUTF(); // 读一个UTF格式字符串
if (s != null)
// 将消息显示在信息显示窗口中
m_textarea.append(s + "\n");
}
} catch (Exception e) {
m_textarea.append("Network problem or Server down.\n");
m_textfield.setVisible(false);
}
}
public void stop() {
try {
m_out.writeUTF("leave");
} catch (IOException e) {
}
}
public static void main(String[] args) {
// TODO 自动生成方法存根
}
}
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer {
/**
* @param args
* m_threads是一个Vector静态变量,维护所有Server方的ServerThread对象,
* 通过该变量能向所有加入聊天室的聊天者ChatApplet广播信息,撤销退出的聊天者。
* 聊天服务者ChatServer的主方法。该方法监听聊天者Chat Applet的请求, 并为新连接的聊天者创建一个服务线程。
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket socket = null;
Vector m_threads = new Vector();
System.out.println("listen...");
try {
// 设置ServerSocket监听端口号为5555,这个数字必须和程序聊天者ChatApplet中的port参数一致
socket = new ServerSocket(5555);
} catch (Exception e) {
System.out.println("new ServerSocket() failed!");
return;
}
try {
int nid = 0;
while (true) {
// 监听是否有新聊天者Chat Applet连接到聊天Server,
// 线程运行到该语句会封锁,直到有新的连接产生
Socket s = socket.accept();
System.out.println("accepted");
// 创建一个新的ServerThread
ServerThread st = new ServerThread(s, m_threads);
// 为该线程设置一个ID号
st.setID(nid++);
// 将线程加入到m_threads Vector中
m_threads.addElement(st);
// 启动服务线程
new Thread(st).start();
// 通知所有ChatApplet有一个新的网友加入
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st1 = (ServerThread) m_threads.elementAt(i);
st1.write("<#>welcome" + st.getID() + "to enter chatroom!");
}
System.out.println("Listen again...");
}
} catch (Exception e) {
System.out.println("Server is down...");
}
}
}
// 监听线程,监听对应的Chat Applet是否有信息传来
class ServerThread implements Runnable {
Vector m_threads;
Socket m_socket = null;
DataInputStream m_in = null;
DataOutputStream m_out = null;
int m_nid;
// 初始化线程
public ServerThread(Socket s, Vector threads) {
m_socket = s;
m_threads = threads;
try {
// 构造数据输入、输出流对象
m_in = new DataInputStream(m_socket.getInputStream());
m_out = new DataOutputStream(m_socket.getOutputStream());
} catch (Exception e) {
}
}
public void run() // 线程的执行体
{
System.out.println("thread is running");
try {
while (true) {
// 监听对应的ChatApplet是否传来消息
// 线程封锁在m_in.readUTF()中,直到有信息传来才返回
String s = m_in.readUTF();
if (s == null)
break;
// 如果Chat Applet传来的信息为“leave”,则通知所有其他的ChatApplet自己推出了
if (s.trim().equals("leave"))
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st = (ServerThread) m_threads.elementAt(i);
st.write("***" + getID() + "leave..." + "***");
}
else
// 向所有ChatApplet广播该消息
for (int i = 0; i < m_threads.size(); i++) {
ServerThread st = (ServerThread) m_threads.elementAt(i);
st.write("<" + getID() + ">" + s);
}
} // while(true)
} catch (Exception e) {
e.printStackTrace();
}
// 从m_threads Vector中删除该线程,表示该线程已经离开聊天室
m_threads.removeElement(this);
System.out.println("remove element!");
try {
m_socket.close();
} catch (Exception e) {
}
}
// 将msg送回对应的Applet
public void write(String msg) {
synchronized (msg) {
try {
m_out.writeUTF(msg);
} catch (IOException e) {
}
}
}
public int getID() // 获得该线程的ID
{
return m_nid;
}
public void setID(int nid) // 设置线程的ID
{
m_nid = nid;
}
}
//////////////
package cn.apr.chart;
import java.awt.*;
import java.applet.*;
import java.io.*;
import java.net.*;
//继承Applet,实现Runnable
public class ChatApplet1 extends Applet implements Runnable {
TextArea m_textarea; // 接受消息显示窗口
TextField m_textfield; // 发送消息输入窗口
DataInputStream m_in; // 消息输入流
DataOutputStream m_out; // 消息输出流
/**
* @param args
* ChatApplet的初始化方法
*/
public void init() {
// 创建窗口
setLayout(null);
setSize(426, 266);
m_textarea = new TextArea(10, 10);
m_textfield = new TextField();
m_in = null;
m_out = null;
// 初始化Appleton,并连接到聊天服务者
try {
// 获取applet的URL,即通过服务器地址
URL url = getCodeBase();
// 获取服务器IP地址
InetAddress inetaddr = InetAddress.getByName(url.getHost());
Socket m_socket;
// 屏幕显示服务器IP地址、通信协议
System.out.println("Server:" + inetaddr + "" + url.getHost() + ""
+ url.getProtocol());
// 创建与服务器IP地址连接的套接口,5555是聊天服务器套接口端口
m_socket = new Socket(inetaddr, 5555);
// 在套接口上建立输入流
m_in = new DataInputStream(m_socket.getInputStream());
// 在套接口上建立输出流
m_out = new DataOutputStream(m_socket.getOutputStream());
} catch (Exception e) {
System.out.println("Error:" + e);
}
setLayout(new BorderLayout());
add("Center", m_textarea);
add("South", m_textfield);
m_textarea.setEditable(false);
// 启动监听线程
new Thread(this).start();
}
// 当聊天者在消息输入窗口键入回车后,读取字符串,发送给聊天服务者。
public boolean handleEvent(Event event) {
String b = m_textfield.getText();
if ((event.target == m_textfield) && (event.id == Event.ACTION_EVENT)) {
m_textfield.setText("");
// 将聊天者输入的消息发送给ChatServer
try {
m_out.writeUTF(b); // 向聊天服务者发送一个UFT格式字符串
} catch (IOException e) {
}
return true;
} else
return super.handleEvent(event);
}
// 聊天者监听对应的服务线程,在读取对应服务线程传来的消息,并显示在通信显示窗口中
public void run() {
try {
while (true) {
// 聊天者监听对应服务线程发来的消息,它将封锁在该语句中,直到消息到来
String s = m_in.readUTF(); // 读一个UTF格式字符串
if (s != null)
// 将消息显示在信息显示窗口中
m_textarea.append(s + "\n");
}
} catch (Exception e) {
m_textarea.append("Network problem or Server down.\n");
m_textfield.setVisible(false);
}
}
public void stop() {
try {
m_out.writeUTF("leave");
} catch (IOException e) {
}
}
public static void main(String[] args) {
// TODO 自动生成方法存根
}
}
package cn.apr.socket; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class MyClient { protected Shell shell; private Text textChatInfo; private Text textMsg; /** * Launch the application. * * @param args */ public static void main(String[] args) { try { MyClient window = new MyClient(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window. */ public void open() { Display display = Display.getDefault(); createContents(); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } /** * Create contents of the window. */ protected void createContents() { shell = new Shell(); shell.setSize(450, 300); shell.setText("SWT Application"); GridLayout layout = new GridLayout(3, false); shell.setLayout(layout); /* line begin */ Label lblServerIp = new Label(shell, SWT.NONE); lblServerIp.setAlignment(SWT.RIGHT); lblServerIp.setText("IP:"); Text textServerIP = new Text(shell, SWT.BORDER); GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.horizontalSpan = 2; gd.widthHint = 200; textServerIP.setLayoutData(gd); textServerIP.setText("127.0.0.1"); /* line begin */ Label lblPort = new Label(shell, SWT.NONE); lblPort.setAlignment(SWT.RIGHT); lblPort.setText("Port:"); Text textServerPort = new Text(shell, SWT.BORDER); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.horizontalSpan = 2; textServerPort.setLayoutData(gd); textServerPort.setText("6666"); /* line begin */ new Label(shell, SWT.NONE); Text textChatInfo = new Text(shell, SWT.BORDER|SWT.MULTI); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.verticalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; gd.horizontalSpan = 2; gd.heightHint = 150; textChatInfo.setLayoutData(gd); /* line begin */ new Label(shell, SWT.NONE); Text textMsg = new Text(shell, SWT.BORDER ); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.horizontalSpan = 1; gd.grabExcessHorizontalSpace = true; textMsg.setLayoutData(gd); Button btnSend = new Button(shell, SWT.NONE); btnSend.setText("Send"); gd = new GridData(); gd.grabExcessHorizontalSpace = true; btnSend.setLayoutData(gd); } }
相关文章推荐
- eclipse插件开发入门——使用command实现在资源管理器中定位资源
- 7月20日Java基础:本人为新手正在学习Java中把每天学的东西晚上都会在博客记录希望大神可以指点 不足在此谢过。
- 4. JavaSE-数组 & 常用算法
- 3. JavaSE-位运算及判断循环程序结构的讲解
- Eclipse
- 用记事本写一个简单的java程序
- Ubuntu 14.04 Eclipse JNI环境搭建(一)之生成JNI头文件
- 几个java小问题
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
- java基础---HashMap和HashTable的异同之处
- Java中的异常处理
- spring mvc 基础学习
- 使用Spring MVC 4构建Restful服务
- 深入浅出理解 | Java 内存模型
- java.net.ConnectException: localhost/127.0.0.1:8088 - Connection refused
- Java基础总结(一)
- 欢迎使用CSDN-markdown编辑器
- Spring MVC 重定向
- SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component
- java jdbc 连接池