您的位置:首页 > 编程语言 > Java开发

聊天程序初级版

2017-10-11 15:38 127 查看
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ChatServer {
/**
* 8.2、接收多个信息,建立两个条件判断
*/
boolean started = false;
ServerSocket ss = null;
List<Client> clients = new ArrayList<Client>();

public static void main(String[] args) {
new ChatServer().start();
}

public void start() {
/**
* 5、创建服务端的连接端口号ServerSocket,并接受客户端的连接accept
* 打印System.out.println("a client connetion")作为测试
*/
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();
System.out.println("a client connetion");
Client c = new Client(s);
new Thread(c).start();
clients.add(c);
}
} catch (IOException e){
e.printStackTrace();

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

}
/**
* 10、建立线程处理客户端
*/
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;
/**
* 7.2、建立输入流,读取客户端输入的数据
*/
try{
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;  //接收到连接后为真
}  catch (IOException e){
e.printStackTrace();
}
}

/**
* 11、服务端接收客户端信息并发送给客户端
*/
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
clients.remove(this);  //当其中一个client退出的时候要移除list里面的内容,移除当前对象的内容,用this。
System.out.println("对方已退出!");
}
}

@Override
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
System.out.println(str);
for(int i = 0;i<clients.size();i++){
Client c = clients.get(i);
c.send(str);
}
/*
for(Iterator<Client> it = clients.iterator();it.hasNext();) {
Client c = it.next();
c.send(str);
}

Iterator<Client> it = clients.iterator();
while(it.hasNext()){
Client c =it.next();
c.send(str);
}
*/
}
} catch (EOFException e) {
System.out.println("client closed");

} catch (IOException e){
e.printStackTrace();

/**
* 9、调整bug,将程序写得更健壮,打印友好提示信息
*/
} finally {
try {
if(dis != null){
dis.close();
}

if(dos != null){
dos.close();
}

if(s != null) {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

}
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

public class ChatClient extends Frame {
Socket s = null;  //成员变量,方便拿到socket里面的内容
DataOutputStream dos = null;
DataInputStream dis = null;
private boolean bConnected = false;
Thread tRecv = new Thread(new RecvThread());
/**
* 2、添加TextField文本输入框,添加TestArea下拉条
*/
TextField tfTex = new TextField();
TextArea taContent = new TextArea();

public static void main(String[] args) {
new ChatClient().luanchFrame();
}

public void luanchFrame(){

/**
* 1、首先创建窗口
*/
this.setLocation(300, 400);
this.setSize(400, 500);
this.add(tfTex, BorderLayout.SOUTH);  //两个参数,设定传入的方向,BorderLayout区域划分为:东西南北中
this.add(taContent, BorderLayout.EAST);
pack();  //将区域包裹,不留空白区域

/**
* 3、添加窗口关闭的功能,这里使用匿名类(没有名字的类)。(其它两种,并排的监听器类、内部类)
*/
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
disconnect();  //关闭窗口的时候调用断开连接的方法
System.exit(0);
}

});
tfTex.addActionListener(new TFListener());
this.setVisible(true);
connect();
tRecv.start();
}

/**
* 6、与服务器建立连接Socket(主机,端口号)
*  打印一句话作为测试
*/
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("connect");
bConnected = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 8.1、当连接断开的时候,关闭socket
*/
public void disconnect() {
try {
bConnected = false;
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}

/*
try {
bConnected = false;
tRecv.join();

} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
}

/**
* 4、将输入框的内容显示到显示区域。这里使用内部类(方便修改以及添加内容,不被其它内调用)
*/
private class TFListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
String str = tfTex.getText().trim();  //得到输入框的内容
//			taContent.setText(str);  //显示到TextArea
tfTex.setText("");   //将输入框的内容输出后,设置为空

/**
* 7.1、建立输出流,向服务器端写入内容
*    定义为成员变量,创建对象放到连接里,连接不断开就可以一直向服务器发送信息
*/
try {
dos.writeUTF(str);
dos.flush(); //添加冲刷/刷新
} catch (IOException e1) {
e1.printStackTrace();
}

}

}

/**
* 12、启用线程接收服务器发送的信息
*/
public class RecvThread implements Runnable {

@Override
public void run() {
try{
while(bConnected){
String str = dis.readUTF();
//					System.out.println(str);
taContent.setText(taContent.getText() + str +"\n");
}
} catch(SocketException e) {
System.out.println("a client 已退出!");
}catch(IOException e) {
e.printStackTrace();
}
}

}
}











                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  聊天 java