socket连接服务端和客户端的新demo,扩展性更好,更适合用于项目中。
2013-06-14 12:18
519 查看
要用socket来连接服务端、客户端,简单的连接和获取数据不难,但要贯通整个项目的话,使用起来就难了。写了两三个demo,最终这个demo是最让我满意的。现在提供测试的服务端源码和客户端demo。
服务端源码:
客户端代码太多了,就展示一些主要代码吧。
clientInputThread:
clientOutputThread:
Cliend:
MyApplication:
GetMsgService:
MyActivity:
LoginActivity:
MyChatActivity:
ChatMsgViewAdapter:
ChatMsgEntity:
测试效果的图片,我也想黏贴上去,不知道怎弄。流程就是登陆成功后,跳转到MyChatActivity的界面,这个界面会不断从输入流读出数据到控件中。
文章的源代码,欢迎下载!
服务端源码:
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(){ @Override public 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(); } } @Override public 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(); } } @Override public 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); } @Override public 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; @Override public 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; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); application = (MyApplication) this.getApplicationContext(); client = application.getClient(); } @Override public 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); } }); } } @Override public 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() { @Override public 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(); } @Override public void onStart() { super.onStart(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.demo.receiver"); registerReceiver(MsgReceiver, intentFilter); } @Override protected 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; @Override protected 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登录", // "亲!服务器暂未开放哦"); // } } @Override public 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(); } } @Override public String getM() { return super.getM(); } @Override protected void onResume() { super.onResume(); Intent service = new Intent(this, GetMsgService.class); startService(service); } @Override protected void onStop() { super.onStop(); } @Override protected 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; @Override protected 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); } @Override public void onStart() { super.onStart(); } @Override protected void onResume() { super.onResume(); } @Override public 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); } @Override public 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的界面,这个界面会不断从输入流读出数据到控件中。
文章的源代码,欢迎下载!
相关文章推荐
- 最近在看socket连接,学习了一点适合新手学习,socket客户端和服务端长连接,废话就不多说了,大家看了就明白了
- 客户端分段读取服务端的socket信息 客户端连接多台socket服务端
- SOCKET客户端与服务端长时间通信后,会连接不上服务端的问题,以及server端UDP丢包的问题
- java Socket 多个客户端连接同一个服务端
- 简单的socket连接,实现服务端可以获得多个客户端连接(备份,方便以后查询)
- C#/.net学习-14-一个socket监管客户端与服务端的小demo
- nodejs socket长连接服务端和测试客户端
- 基于Socket的TCP长连接(服务端Java+客户端Android),Service配合AIDL实现
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
- Java Socket实现多个客户端连接同一个服务端
- QTcpSocket客户端、服务端互发字符串Demo
- 使用Socket,让连接客户端可以对服务端执行相应的指令
- 【socket编程】 一个简单的基于TCP连接的客户端、服务端用例
- java实现socket客户端连接服务端
- java Socket 长连接 心跳包 客户端 信息收发 demo
- 网络 TCP net 服务端和客户端进行连接 io SerrverSocket Socket(accept) Thread
- C# socket服务端判断 客户端已经断开连接的一个小办法
- 无连接Socket中服务端对客户端的记录
- 使用Node.js+socket.io制作服务端,unity+socket.io for unity 制作客户端 ,验证位置同步Demo
- SQLiteServer+SQLiteClient 用于.Net项目的SQLite服务端程序和客户端类库