基于Socket的局域网简易聊天室

主要是通过Socket进行编程

Scoket与ServerSocket交互的过程:

1)服务器端程序创建一个ServerSocket,然后调用accept()方法等待客户端进行连接

2)客户端程序创建一个Socket并请求与服务器端程序建立连接

3) 服务器端程序接受客户端的连接请求,并创建一个新的Socket与该客户端建立专线连接

4)建立了连接的客户端及服务器端的两个Socket在一个由服务器端程序创建的单独的线程上进行对话,对话的方式采用getInputStream(),getOutputStream()进行信息的输入输出。

服务器端程序:

package org.chat.com.server;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;

public class ServerThread extends Thread {

	ServerSocket serverSocket;
	public static final int PORT=8521;
	//负责接收客户端发来的消息,存储所有与服务器端建立连接的客户端
	public Vector clients;
	//创建一个Vector对象,用于存储客户端发过来的消息
	public Vector messages;
	
	//负责向客户端广播消息
	BroadCast broadCast;
	
	String ip;
	InetAddress myIPaAddress=null;
	public ServerThread(){
		clients=new Vector();
		messages=new Vector();
		
		try {
			//创建serverScoket对象
			serverSocket=new ServerSocket(PORT);
		} catch (IOException e) {}
		try {
			myIPaAddress=InetAddress.getLocalHost();
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			System.out.println(e1.toString());
		}
		ip=myIPaAddress.getHostAddress();
		Server.jTextArea.append("服务器地址:"+ip+"  端口号:"+String.valueOf(serverSocket.getLocalPort())+"\n");
		
		//创建广播信息线程并启动
		broadCast=new BroadCast(this);
		broadCast.start();
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			try {
				//获取客户端连接,并返回一个新的Socketd对象
				Socket socket=serverSocket.accept();
				System.out.println(socket.getInetAddress().getHostAddress());
				//创建clientThread线程,用于监听该连接对应的客户端是否发送消息过来,并获取消息
				ClientThread clientThread=new ClientThread(socket,this);
				clientThread.start();
				if(socket!=null){
					synchronized (clients) {
						clients.addElement(clientThread);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("建立客户端连接失败");

			}
			
		}
	}
	public void finalize(){
		try {
			serverSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		serverSocket=null;
	}
}
 
  
package org.chat.com.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;


/***
 * 用于监听该客户端是否有消息,维持服务器与单个客户端之间的连接
 * @author zzg
 *
 */
public class ClientThread extends Thread {

	Socket clientSocket;
	DataInputStream in=null;
	public DataOutputStream out=null;
	
	ServerThread serverThread;
	String str;
	
	public static int ConnectNumber=0;
	
	public ClientThread(Socket socket,ServerThread serverThread){
		clientSocket=socket;
		this.serverThread=serverThread;
		try {
			in=new DataInputStream(clientSocket.getInputStream());
			out=new DataOutputStream(clientSocket.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("发送异常,建立I/O通道失败");
		}	
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			try {
				//接收客户端发来的消息
				String message=in.readUTF();
				synchronized (serverThread.messages) {
					if(message!=null){	
						serverThread.messages.addElement(message);
						Server.jTextArea.setText(message+"\n");
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	
}

package org.chat.com.server;

import java.io.IOException;


/***
 * 向所有的客户端发送message数组中尚未发送出去的消息
 * @author zzg
 *
 */
public class BroadCast extends Thread {

	ClientThread clientThread;
	ServerThread serverThread;
	String str;
	
	public BroadCast(ServerThread serverThread){
		this.serverThread=serverThread;
	}
	@Override
	public void run() {
		//不断向所有客户端发送消息
		while(true){
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized (serverThread.messages) {
				//判断是否有未发送的消息
				if(serverThread.messages.isEmpty()){
					continue;
				}
				str=(String) this.serverThread.messages.firstElement();
			}
			synchronized (serverThread.clients) {
				for(int i=0;i

package org.chat.com.server;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;



public class Server extends JFrame implements ActionListener  {

	BorderLayout borderLayout=new BorderLayout();
	BorderLayout borderLayout2=new BorderLayout();
	
	JPanel jPanel1=new JPanel();
	JPanel jPanel2=new JPanel();
	
	JButton jButton1=new JButton();
	JButton jButton2=new JButton();
	
	JScrollPane jScrollPane=new JScrollPane();
	
	public static JTextArea jTextArea=new JTextArea();
	boolean bool=false;
	boolean start=false;
	
	ServerThread serverThread;
	Thread thread;
	
	public Server(){
		super("server");
		getContentPane().setLayout(borderLayout);
		
		jButton1.setText("启动服务器");
		jButton2.setText("关闭服务器");
		
		jButton1.addActionListener(this);
		jButton2.addActionListener(this);
		
		this.getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
		
		jPanel1.add(jButton1);
		jPanel1.add(jButton2);
		
		jTextArea.setText("");
		jPanel2.setLayout(borderLayout2);
		jPanel2.add(jScrollPane,java.awt.BorderLayout.CENTER);
		jScrollPane.getViewport().add(jTextArea);
		this.getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
		
		this.setSize(400,400);
		this.setVisible(true);
	}

	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource()==jButton1){
			serverThread=new ServerThread();
			serverThread.start();
		}else if(e.getSource()==jButton2){
			bool=false;
			start=false;
			serverThread.finalize();
			this.setVisible(false);
		}
	}
	public static void main(String[] args) {
		Server server=new Server();
		server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}
客户端程序:

package com.example.chartdemo;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.SimpleFormatter;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener,Runnable {

	public static final int PORT=8521;
	EditText et_name;
	EditText et_ip;
	EditText et_history;
	Button btn_exit;
	Button btn_enter;
	EditText et_message;
	Button btn_send;
	private String name;//用户名
	private String ip;//ip
	private String chat_txt;//发言信息
	private String chat_in;//从服务器接受的信息
	Socket socket;
	Thread thread;
	DataInputStream in;
	DataOutputStream out;
	boolean flag=false;//是否登陆的标志
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		setListener();
	}
	private void setListener() {
		// TODO Auto-generated method stub
		btn_exit.setOnClickListener(this);
		btn_enter.setOnClickListener(this);
		btn_send.setOnClickListener(this);
	}
	private void initView() {
		// TODO Auto-generated method stub
		et_name=(EditText) findViewById(R.id.et_username);
		et_ip=(EditText) findViewById(R.id.et_hostIP);
		btn_exit=(Button) findViewById(R.id.btn_exit);
		btn_enter=(Button) findViewById(R.id.btn_enter);
		
		et_history=(EditText) findViewById(R.id.et_history);
		
		et_message=(EditText) findViewById(R.id.et_message);
		
		btn_send=(Button) findViewById(R.id.btn_send);
	}
	 String nowStr="";
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Date now=new Date(System.currentTimeMillis());
		SimpleDateFormat format=new SimpleDateFormat();
		nowStr=format.format(now);
		switch(v.getId()){
		case R.id.btn_exit:
			if(flag==false){
				Toast.makeText(this,"未登陆",1).show();
				return ;
			}
			try {
				out.writeUTF("=="+name+"已经退出了");
				out.close();
				in.close();
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			flag=false;
			Toast.makeText(this,"退出!",1).show();
			break;
		case R.id.btn_enter:
			if(flag==true){
				Toast.makeText(this,"已经登录过了",1).show();
				return ;
			}
			name=et_name.getText().toString().trim();
			ip=et_ip.getText().toString().trim();
			if(!name.equals("")|| name!=null && ip!=null || !ip.equals("")){;
				thread=new Thread(this);
				thread.start();
				flag=true;
			}else{
				Toast.makeText(this,"未登陆",1).show();
				return ;
			}
			break;
		case R.id.btn_send:
			if(flag==false){
				Toast.makeText(this,"未登陆",1).show();
				return ;
			}
			chat_txt=et_message.getText().toString();
			if(chat_txt!=null||!chat_txt.equals("")){
				try {
					out.writeUTF("^_^"+name+" "+nowStr+"说\n"+chat_txt);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}else{
				try {
					out.writeUTF("请说话");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			et_message.setText("");
			break;
		}
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			socket=new Socket(ip,PORT);
			in=new DataInputStream(socket.getInputStream());
			out=new DataOutputStream(socket.getOutputStream());
			out.writeUTF("$$"+name+" "+nowStr+"上线了");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		while(true){
			
			try {
				//读取服务器端发送过来的数据
				chat_in=in.readUTF();
				chat_in=chat_in+"\n";
				handler.sendMessage(handler.obtainMessage());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			et_history.append(chat_in);
		};
	};
}



你可能感兴趣的:(Android)