主要是通过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
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);
};
};
}