socket连接服务端和客户端的新demo,扩展性更好,更适合用于项目中。

来源:互联网 发布:Js回车切换表单焦点 编辑:程序博客网 时间:2024/06/06 16:30

要用socket来连接服务端、客户端,简单的连接和获取数据不难,但要贯通整个项目的话,使用起来就难了。写了两三个demo,最终这个demo是最让我满意的。现在提供测试的服务端源码和客户端demo。

服务端源码:

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class ServerTest {/** * @param args */static Socket socket = null;static DataOutputStream out = null;static DataInputStream in = null;public static void main(String[] args) throws IOException {ServerSocket s = new ServerSocket(10213);socket = s.accept(); out = new DataOutputStream(socket.getOutputStream()); out.writeBytes("[Connection]True");  in = new DataInputStream(socket.getInputStream()); int r = in.available();  while(r==0){   r = in.available();  }  byte[] b = new byte[r];in.read(b);String result = new String(b,"utf-8"); if(result.equals("[login]|9a01be167a2b0ff756e7e8da9e29f881|c4ca4238a0b923820dcc509a6f75849b")) { out.writeBytes("login success!");Thread m = new Thread(new Runnable(){@Overridepublic void run() {while(true){for(int i =0;i<5;i++){try {Thread.sleep(10000);out.writeBytes("heelo!"+i);System.out.println("heelo!"+i);} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}try {out.flush();out.close();} catch (IOException e) {e.printStackTrace();}}}});m.start(); } }}

客户端代码太多了,就展示一些主要代码吧。

clientInputThread:

import java.io.DataInputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OptionalDataException;import java.net.Socket;import android.util.Log;public class ClientInputThread extends Thread{private Socket socket;private DataInputStream in;private boolean isStart = true;private MessageListener messageListener;public ClientInputThread(Socket socket) {this.socket = socket;try {in = new DataInputStream(socket.getInputStream());} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try {byte[] buffer = new byte[1024];while(isStart){int readSize = in.read(buffer);if (readSize > 0) {String msg = new String(buffer, 0, readSize);messageListener.Message(msg);Log.v("in", "in...."+readSize+"  "+msg);}}in.close();if(socket != null){socket.close();}} catch (OptionalDataException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}public MessageListener getMessageListener() {return messageListener;}public void setMessageListener(MessageListener messageListener) {this.messageListener = messageListener;}public Socket getSocket() {return socket;}public void setSocket(Socket socket) {this.socket = socket;}public DataInputStream getIn() {return in;}public void setIn(DataInputStream in) {this.in = in;}public boolean isStart() {return isStart;}public void setStart(boolean isStart) {this.isStart = isStart;}}

clientOutputThread:

import java.io.DataOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.net.Socket;public class ClientOutputThread extends Thread{private Socket socket;private DataOutputStream out;private boolean isStart = true;private String msg;public ClientOutputThread(Socket socket){this.socket = socket;try {out = new DataOutputStream(socket.getOutputStream());} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try{while(isStart){if (msg != null) {out.writeBytes(msg);out.flush();synchronized (this) {wait();}}}out.close();if (socket != null)socket.close();}catch(Exception e){e.printStackTrace();}}public Socket getSocket() {return socket;}public void setSocket(Socket socket) {this.socket = socket;}public DataOutputStream getOut() {return out;}public void setOut(DataOutputStream out) {this.out = out;}public boolean isStart() {return isStart;}public void setStart(boolean isStart) {this.isStart = isStart;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}

Cliend:

import java.io.IOException;import java.net.InetSocketAddress;import java.net.Socket;public class Client {private Socket socket;private ClientThread clientThread;private String ip;private int port;public Client(String ip, int port) {super();this.ip = ip;this.port = port;}public boolean conn() {try {socket = new Socket();socket.connect(new InetSocketAddress(ip, port), 3000);if (socket.isConnected()) { System.out.println("Connected.."+socket.isConnected());clientThread = new ClientThread(socket);clientThread.start();}} catch (IOException e) {e.printStackTrace();return false;}return true;}public ClientInputThread getClientInputThread() {return clientThread.getIn();}public ClientOutputThread getClientOutputThread() {return clientThread.getOut();}public void setIsStart(boolean isStart) {clientThread.getIn().setStart(isStart);clientThread.getOut().setStart(isStart);}//**********************线程***************************************************public class ClientThread extends Thread{private ClientInputThread in;private ClientOutputThread out;public ClientThread(Socket socket){in = new ClientInputThread(socket);out = new ClientOutputThread(socket);}@Overridepublic void run() {in.setStart(true);out.setStart(true);in.start();out.start();}public ClientInputThread getIn() {return in;}public ClientOutputThread getOut() {return out;}}}

MyApplication:

import com.org.demo.client.Client;import android.app.Application;public class MyApplication extends Application{private Client client;private boolean isClientStart;@Overridepublic void onCreate() {client = new Client("192.168.1.106", 10212);super.onCreate();}public Client getClient() {return client;}public void setClient(Client client) {this.client = client;}public boolean isClientStart() {return isClientStart;}public void setClientStart(boolean isClientStart) {this.isClientStart = isClientStart;}}

GetMsgService:

import com.org.demo.client.Client;import com.org.demo.client.Client.ClientThread;import com.org.demo.client.ClientInputThread;import com.org.demo.client.MessageListener;import com.org.demo.util.MyApplication;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.util.Log;public class GetMsgService extends Service{private static final int MSG = 0x001;private MyApplication application;private Client client;private boolean isStart = false;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();application = (MyApplication) this.getApplicationContext();client = application.getClient();}@Overridepublic void onStart(Intent intent, int startId) {super.onStart(intent, startId);isStart = client.conn();application.setClientStart(isStart);System.out.println("Service : " + isStart);if(isStart){ClientInputThread in = client.getClientInputThread();in.setMessageListener(new MessageListener(){public void Message(String msg) {Intent intent = new Intent();intent.setAction("com.demo.receiver");intent.putExtra("message", msg);sendBroadcast(intent);}});}}@Overridepublic void onDestroy() {super.onDestroy();if (isStart){client.getClientInputThread().setStart(false);client.getClientOutputThread().setStart(false);}}}

MyActivity:

import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.util.Log;public abstract class MyActivity extends Activity{static String msg ; private BroadcastReceiver MsgReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) { msg = intent.getStringExtra("message");if (msg != null) {getMessage(msg);getM();Log.v("MyActivity", msg);} else {close();}}};public abstract void getMessage(String msg);public String getM(){return msg;};public void close() {Intent i = new Intent();i.setAction("com.demo.receiver");sendBroadcast(i);finish();}@Overridepublic void onStart() {super.onStart();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("com.demo.receiver");registerReceiver(MsgReceiver, intentFilter);}@Overrideprotected void onStop() {super.onStop();unregisterReceiver(MsgReceiver);}}

LoginActivity:

import java.io.DataInputStream;import java.io.DataOutputStream;import java.net.Socket;import com.org.demo.client.Client;import com.org.demo.client.ClientOutputThread;import com.org.demo.util.DialogFactory;import com.org.demo.util.MD5;import com.org.demo.util.MyApplication;import com.org.demo02.R;import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class LoginActivity extends MyActivity implements OnClickListener{private EditText usernameT;private EditText passwordT;private Button loginButton;private Message message;private MyApplication application;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.login);usernameT = (EditText) findViewById(R.id.username);passwordT = (EditText) findViewById(R.id.password);loginButton = (Button) findViewById(R.id.login);loginButton.setOnClickListener(this);application = (MyApplication) this.getApplicationContext();}public void onClick(View arg0) {String username = usernameT.getText().toString();String password = passwordT.getText().toString();System.out.println(username+"  "+password);MD5 md5 = new MD5();String ss = "[login]|"+md5.MD5(username)+"|"+md5.MD5(password);//showRequestDialog();if(this.getM().equals("[Connection]True")|| this.getM().equals("Login|false")){Client client = application.getClient();ClientOutputThread out = client.getClientOutputThread();out.setMsg(ss);Log.v("out", ss);showRequestDialog();}// else // {//if (mDialog.isShowing())//mDialog.dismiss();//DialogFactory.ToastDialog(LoginActivity.this, "QQ登录",//"亲!服务器暂未开放哦");// }}@Overridepublic void getMessage(String msg) {Log.v("login", msg);if(msg.endsWith("Login|true")){if (mDialog.isShowing())mDialog.dismiss();Intent intent = new Intent();intent.setClass(LoginActivity.this, MyChatActivity.class);startActivity(intent);finish();Toast.makeText(getApplicationContext(), "登录成功", 0).show();}if(msg.endsWith("Login|false")) {DialogFactory.ToastDialog(LoginActivity.this, "登录","亲!您的帐号或密码错误哦");if (mDialog.isShowing())mDialog.dismiss();}}@Overridepublic String getM() {return super.getM();}@Overrideprotected void onResume() {super.onResume();Intent service = new Intent(this, GetMsgService.class);startService(service);}@Overrideprotected void onStop() {super.onStop();}@Overrideprotected void onDestroy() {Log.v("Login--Destory", "Destory!!!");super.onDestroy();} @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            new AlertDialog.Builder(this)                    // .setIcon(R.drawable.services)                    .setTitle("退出提示")                    .setMessage("确定要退出?")                    .setNegativeButton("取消",                            new DialogInterface.OnClickListener() {                                public void onClick(DialogInterface dialog,                                        int which) {                                }                            })                    .setPositiveButton("退出",                            new DialogInterface.OnClickListener() {                                public void onClick(DialogInterface dialog,                                        int whichButton) {                                                                if (application.isClientStart()) {// 如果连接还在,说明服务还在运行            // 关闭服务            Intent service = new Intent(LoginActivity.this,            GetMsgService.class);            stopService(service);            }                                                                System.exit(0);                                    //finish();                                }                            }).show();            return true;        } else {            return super.onKeyDown(keyCode, event);        }    }     /** * 判断手机网络是否可用 *  * @param context * @return */private boolean isNetworkAvailable() {ConnectivityManager mgr = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo[] info = mgr.getAllNetworkInfo();if (info != null) {for (int i = 0; i < info.length; i++) {if (info[i].getState() == NetworkInfo.State.CONNECTED) {return true;}}}return false;}private void toast(Context context) {new AlertDialog.Builder(context).setTitle("温馨提示").setMessage("亲!您的网络连接未打开哦").setPositiveButton("前往打开",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int which) {Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);startActivity(intent);}}).setNegativeButton("取消", null).create().show();}/** * 点击登录按钮后,弹出验证对话框 */private Dialog mDialog = null;private void showRequestDialog() {if (mDialog != null) {mDialog.dismiss();mDialog = null;}mDialog = DialogFactory.creatRequestDialog(this, "正在验证账号...");mDialog.show();}}

MyChatActivity:

import java.io.IOException;import java.io.ObjectOutputStream;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import com.org.demo.client.Client;import com.org.demo.client.ClientOutputThread;import com.org.demo.util.MyApplication;import com.org.demo02.R;import android.app.Activity;import android.app.AlertDialog;import android.app.Notification;import android.app.NotificationManager;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.provider.MediaStore.Audio;import android.util.Log;import android.view.View;import android.view.Window;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ListView;public class MyChatActivity extends MyActivity{private MyApplication application; private ListView lv_info_contain = null;  private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>(); private ChatMsgViewAdapter mAdapter;  private NotificationManager nm;   private Notification n;  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏setContentView(R.layout.chat);application = (MyApplication) getApplicationContext();lv_info_contain = (ListView) findViewById(R.id.listview);        mAdapter = new ChatMsgViewAdapter(this, mDataArrays);lv_info_contain.setAdapter(mAdapter);}@Overridepublic void onStart() {super.onStart();}@Overrideprotected void onResume() {super.onResume();}@Overridepublic void getMessage(String msg) {Log.v("mychat", msg);initData(msg);mynoti();} public void initData(String str) { ChatMsgEntity entity = new ChatMsgEntity();entity.setName("Eric");entity.setDate(this.getDateEN());entity.setMessage(str);entity.setImg(R.drawable.f8);mDataArrays.add(entity);mAdapter.notifyDataSetChanged();lv_info_contain.setSelection(mAdapter.getCount()); } public static String getDateEN() {SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date1 = format1.format(new Date(System.currentTimeMillis()));return date1;} public void mynoti(){     NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);        Notification mNotification = new Notification();          mNotification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");         mNotification.flags = Notification.FLAG_NO_CLEAR; ;              long[] vir = {0,100,200,300};              mNotification.vibrate = vir;                  mNotificationManager.notify(0, mNotification);    }  @Overridepublic void onBackPressed() {// 捕获返回按键exitDialog(MyChatActivity.this, "提示", "亲!您真的要退出吗?");} /** * 退出时的提示框 *  * @param context *            上下文对象 * @param title *            标题 * @param msg *            内容 */private void exitDialog(Context context, String title, String msg) {new AlertDialog.Builder(context).setTitle(title).setMessage(msg).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {if (application.isClientStart()) {// 如果连接还在,说明服务还在运行// 关闭服务Intent service = new Intent(MyChatActivity.this,GetMsgService.class);stopService(service);}close();// 调用父类自定义的循环关闭方法}}).setNegativeButton("取消", null).create().show();}}

ChatMsgViewAdapter:

import java.util.List;import com.org.demo02.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;/** * 消息ListView的Adapter *  * @author way */public class ChatMsgViewAdapter extends BaseAdapter {private int[] imgs = { R.drawable.f1, R.drawable.f2,R.drawable.f3, R.drawable.f4, R.drawable.f5, R.drawable.f6,R.drawable.f7, R.drawable.f8, R.drawable.f9 };//public static interface IMsgViewType {//int IMVT_COM_MSG = 0;// 收到对方的消�?//int IMVT_TO_MSG = 1;// 自己发�?出去的消�?//}//private static final int ITEMCOUNT = 2;// 消息类型的�?�?private List<ChatMsgEntity> coll;// 消息对象数组private LayoutInflater mInflater;public ChatMsgViewAdapter(Context context, List<ChatMsgEntity> coll) {this.coll = coll;mInflater = LayoutInflater.from(context);}public int getCount() {return coll.size();}public Object getItem(int position) {return coll.get(position);}public long getItemId(int position) {return position;}/** * 得到Item的类型,是对方发过来的消息,还是自己发�?出去�? *///public int getItemViewType(int position) {//ChatMsgEntity entity = coll.get(position);////if (entity.getMsgType()) {// 收到的消�?//return IMsgViewType.IMVT_COM_MSG;//} else {// 自己发�?的消�?//return IMsgViewType.IMVT_TO_MSG;//}//return position;//}/** * Item类型的�?�? *///public int getViewTypeCount() {//return ITEMCOUNT;//}public View getView(int position, View convertView, ViewGroup parent) {ChatMsgEntity entity = coll.get(position);//boolean isComMsg = entity.getMsgType();ViewHolder viewHolder = null;if (convertView == null) {convertView = mInflater.inflate(R.layout.chatting_item_msg_text_right, null);viewHolder = new ViewHolder();viewHolder.tvSendTime = (TextView) convertView.findViewById(R.id.tv_sendtime);viewHolder.tvUserName = (TextView) convertView.findViewById(R.id.tv_username);viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_chatcontent);viewHolder.icon = (ImageView) convertView.findViewById(R.id.iv_userhead);//viewHolder.isComMsg = isComMsg;convertView.setTag(viewHolder);}else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.tvSendTime.setText(entity.getDate());viewHolder.tvUserName.setText(entity.getName());viewHolder.tvContent.setText(entity.getMessage());viewHolder.icon.setImageResource(entity.getImg());return convertView;}static class ViewHolder {public TextView tvSendTime;public TextView tvUserName;public TextView tvContent;public ImageView icon;//public boolean isComMsg = true;}}

ChatMsgEntity:

public class ChatMsgEntity {private String name;private String date;private String message;private int img;//private boolean isComMeg = true;public ChatMsgEntity() {}public ChatMsgEntity(String name, String date, String text, int img) {super();this.name = name;this.date = date;this.message = text;this.img = img;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}//public boolean getMsgType() {//return isComMeg;//}////public void setMsgType(boolean isComMsg) {//isComMeg = isComMsg;//}public int getImg() {return img;}public void setImg(int img) {this.img = img;}}

测试效果的图片,我也想黏贴上去,不知道怎弄。流程就是登陆成功后,跳转到MyChatActivity的界面,这个界面会不断从输入流读出数据到控件中。


文章的源代码,欢迎下载!




原创粉丝点击