精华内容
下载资源
问答
  • 什么时候自己能独立地一套完整程序出来? 转载于:https://www.cnblogs.com/newsoul/archive/2009/04/12/1434337.html
    什么时候自己能独立地写出一套完整的程序出来?

    转载于:https://www.cnblogs.com/newsoul/archive/2009/04/12/1434337.html

    展开全文
  • 对于那些不懂互联网、不了解小程序的小白、新手来讲,又如何制作小程序呢? 接下来,我们就分享下详细的教程: 一、小程序注册与认证 1、如果有已认证的服务号,可选择【复用公众号资质】快速注册认证小程序,首次可...

    越来越多的小微商家从线下卖货的模式开始布局线上卖货渠道,主要目的就是为了拓宽客户来源渠道,增加销量。

    在线上卖货就需要有载体,而小程序作为当下主流的承载服务的工具,成为各个企业商家布局线上卖货的载体。

    对于那些不懂互联网、不了解小程序的小白、新手来讲,又如何制作小程序呢?

    接下来,我们就分享下详细的教程:

    一、小程序注册与认证

    1、如果有已认证的服务号,可选择【复用公众号资质】快速注册认证小程序,首次可免300元认证费;

    如果没有建议注册并认证服务号,再复用资质申请小程序。此方法以后每年都要向腾讯交300元认证费。

    2、如果不需要公众号,可直接申请认证小程序,得有店代申请小程序,可免300元认证费,且长期是已认证状态;

    在这里插入图片描述

    3、小程序注册好后,需在小程序管理后台填写小程序的基本信息。

    二、制作小程序商城

    搭建店铺框架:

    自己在得有店后台就可以搭建小程序商城,有近200套的模板,选择适合的套用就可以,还可自由编辑,把不喜欢的图片替换掉,拖拽变动位置,操作很简单。

    在这里插入图片描述

    在搭建商城首页时,需要注意banner图(广告轮播)、导航、优惠信息的重点布局,这也是吸引用户的最大亮点,如活动促销、新品、折扣等要在显眼的位置展示。

    在这里插入图片描述

    上架商品:

    可以导入第三方商城的商品链接,设置好sku;

    在这里插入图片描述

    也可以标准库导入,比较省心;

    在这里插入图片描述

    完善店铺信息:

    根据经营业务范围设置配送方式,如全国和同城都有业务,可以同时设置物流快递和同城配送,以及到店自提。如果只做本地生活服务的,只需设置同城配送、到店自提,也支持货到付款。

    在这里插入图片描述

    像物流快递,电子面单服务商的对接;

    在这里插入图片描述

    同城配送小票打印机的设置;
    在这里插入图片描述

    把整个线上业务逻辑打通,都可以在得有店后台操作好。

    三、发布审核小程序

    店铺搭建完成,可以提交审核小程序;

    在这里插入图片描述

    当审核状态是“使用中”时,代表小程序审核通过;如果未通过,就需要重新修改,再次提交。

    在这里插入图片描述

    四、申请微信支付

    在线交易,就需要申请微信支付,有两种申请方式:

    1、需要去微信支付官方填写资料,申请下来费率是千分之六,需要配置API密钥,API证书、JSapi支付,需要绑定小程序,绑定得有店。

    不花钱,但流程非常复杂。不懂技术的话,一般操作不了。

    2、得有店代申请,申请下来费率是0.38%,无需复杂的流程配置,由技术人员代操作。

    在这里插入图片描述

    等微信支付配置好之后,就可以正式上线运营了。

    展开全文
  • 一套完整的asp.net开发的网校程序 系统模块 主要功能模块 系统管理 模块管理 角色管理 系统设置 批量授权管理 在线用户管理 版本升级说明 组织结构管理 部门管理 岗位管理 用户管理 门户管理 发布首页 公告管理 ...
  • 系统模块 主要功能模块 系统管理 模块管理 角色管理 系统设置 批量授权管理 ...我的消息 新消息 收件箱 发件箱 草稿箱 通讯录 通讯录分类管理 我的档案 学习履历 我的账户 个人资料 修改密码
  • 是用php+mysql的,网络上很多,但是都不全,或者就是要资源的, 哪位能提供一套完整的留意版程序?数据库最好有sql脚本
  • 1. 创建uniapp的uniCloud数据库,绑定...2. uniapp微信小程序中授权的登陆。 2.1 创建tool.js文件: export default{ getTokenValue(options) { //1.获取用户的token let { success, fail, complete...

    1. 创建uniapp的uniCloud数据库,绑定云数据库。参考https://uniapp.dcloud.io/uniCloud/concepts/space

    绑定之后再uniCloud控制台查看管理。

     2. uniapp微信小程序中授权的登陆。

         2.1 创建tool.js文件:

    export default{
        getTokenValue(options) {  //1.获取用户的token
    		let {
    			success,
    			fail,
    			complete
    		} = options
    		var _this = this;
    		uni.login({ //获取微信用户的code值
    			provider: 'weixin',
    			success(r) {
    				if (r.code) {
    					uni.getUserInfo({ //获取微信用户的encryptedData,iv值
    						provider: 'weixin',
    						success(res) {		
    							let data={
    								code: r.code,
    								signature: res.signature,
    								encrypted_data: res.encryptedData,
    								iv: res.iv,
    								userInfo:res.userInfo
    							}											
    							uniCloud.callFunction({
    								name: 'ace-login',
    								data: data,
    							}).then((result) => {
    								console.log('微信授权成功',result);
    								if(result.success && result.result && result.result.status===1){								
    									_this.uniSetStorage('token',result.result.token)
    									_this.uniSetStorage('userInfo',result.result.userInfo)
    									complete && complete()
    									success ? success() : false	
    								}else{
    									_this.uniShowToast({
    										title: "用户登陆失败",
    										icon: "none"
    									})
    								}
    															
    							}).catch((err) => {
    								console.log(err);							
    							})
    												
    						},
    						fail:(err)=>{
    							_this.uniShowToast({
    								title: "获取用户信息失败",
    								icon: "none"
    							})
    							complete ? complete() : false
    						}
    					});
    				} else {
    					_this.uniShowToast({
    						title: "获取微信登录login的code失败!",
    						icon: "none"
    					})
    					complete ? complete() : false
    				}
    			}
    		});
    	},
        uniShowToast(options) {  //2.提升框
    		let {
    			title,
    			icon,
    			mask,
    			duration,
    			image
    		} = options
    		uni.showToast({
    			title: title,
    			icon: icon ? icon : "success",
    			image: image ? image : "",
    			mask: mask ? mask : false,
    			duration: duration ? duration : 1500,
    			complete: () => {
    				setInterval(() => {
    					uni.hideToast();
    				}, 30000)
    			}
    		});
    	},
        isGetLocation(type = "scope.userInfo", success = null, fail = null) {  //3. 判断是否授权
    		let _this = this
    		uni.getSetting({
    			success(res) {			
    				if (!res.authSetting[type]) {
    					_this.getAuthorizeInfo(type, success, fail)
    				} else {
    					if(type==='scope.getUserInfo'){
    						if(_this.uniGetStorage("token")){
    							success ? success() : false
    						}else{
    							_this.getTokenValue({
    								success:()=>{
    									success ? success() : false
    								}				
    							})
    						}			
    					}else{
    						success ? success() : false
    					}			
    				}
    			}
    		});
    	},
    	getAuthorizeInfo(type, success, fail) {  //4. 进行授权
    		let _this = this
    		uni.authorize({
    			scope: type,
    			success() {
    				if(type==='scope.getUserInfo'){
    					if(_this.uniGetStorage("token")){
    						success ? success() : false
    					}else{
    						_this.getTokenValue({
    							success:()=>{
    								success ? success() : false
    							}				
    						})
    					}			
    				}else{
    					success ? success() : false
    				}	
    			},
    			fail() {
    				if (fail) {
    					fail()
    				} else {
    					_this.uniShowToast({
    						title: "你拒绝了授权!",
    						icon: "none"
    					})
    					console.log("你拒绝了授权")
    				}
    			}
    		})
    	},
    	
    }

         2.2 main.js中全局引入tool.js文件:

    import tool from "@/common/js/tool.js"
    Vue.prototype.$tool=tool

        2.3 在my.vue页面中使用:

    onLoad(){
    	this.init()
    },
    methods:{
    	init(){
    		this.$tool.isGetLocation('scope.userInfo',()=>{
    			//已经授权,获取用户信息成功
    	    },()=>{
    			//没有授权,需要主动授权
    		})
    	},
    }

        2.4 主动授权页面:

    <template>
    	<view class="auto-login">
    		<view class="content flex flex-column a-center j-center">
    			<view class="title">{{status==='userInfo'?'授权登陆':'授权地址位置'}}</view>
    			<view class="info-msg">
    				请授权头像等信息,以便我们为您提供更好的服务
    			</view>
    			<button open-type="getUserInfo" @getuserinfo="bindGetUserInfo" class="btn" :loading="loading" :disabled="loading" v-if="status==='userInfo'">
    				微信一键登录
    			</button>		
    			<button @click="handler" class="btn"  v-if="status==='userLocation'">
    				授权地址位置
    			</button>
    		</view>
    	</view>
    </template>
    
    <script>
    	export default{
    		props:{
    			status:{
    				type:String,
    				default:"userInfo"
    			},		
    		},
    		data(){
    			return{
    				loading:false
    			}
    		},
    		methods:{
    			bindGetUserInfo(e){
    				var _this=this;		
    				if (e.detail.userInfo){	
    					this.loading=true
    					uni.getSetting({
    					  success(res1) {    	   
    						console.log("res1",res1)
    						if (!res1.authSetting['scope.userInfo']) {//未授权getUserInfo            	
    						  uni.authorize({
    							scope: 'scope.getUserInfo',
    							success(res2) {	  
    								_this.$tool.getTokenValue({
    									success:()=>{
    										_this.$emit("loginOk",true)
    									},
    									complete:()=>{
    										_this.loading=false	
    									}
    								})
    							},
    							fail(err){  
    								_this.$tool.uniShowToast({
    									title: "您拒绝了授权,无法获取小程序信息,请前往授权",
    									icon: "none"
    								})
    								_this.loading=false	
    							}
    						  })
    						}else{//已授权	
    							_this.$tool.getTokenValue({
    								success:()=>{
    									_this.$emit("loginOk",true)
    								},
    								complete:()=>{
    									_this.loading=false	
    								}
    							})
    						}
    					  }
    					})												
    				} else {
    					_this.$tool.uniShowToast({
    						title: "用户拒绝了授权",
    						icon: "none"
    					})
    				}
    			},		
    			handler(){
    				let _this=this
    				uni.openSetting({
    				  success(res) {
    				    console.log(res.authSetting)
    					if(res.authSetting['scope.userLocation']){
    						_this.$emit("loginOk",true)
    					}
    				  }
    				})
    			},
    		}
    	}
    </script>
    
    <style scoped lang="less">
    .auto-login{
    	background: rgba(0,0,0,0.6);
    	z-index: 99999;
    	position: fixed;
    	top: 0;
    	right: 0;
    	bottom: 0;
    	left: 0;
    	display: flex;
    	justify-content: center;
    	align-items: center;
    	.content{
    		width: 500rpx;
    		height: 600rpx;
    		background: white;
    		border-radius: 8rpx;
    		.title{
    			font-size: 34rpx;
    			margin-bottom: 80rpx;
    			font-weight: bold;
    			width: 100%;
    			text-align: center;
    			color: black;
    		}
    		.info-msg{
    			font-size: 28rpx;
    			margin-bottom: 60rpx;
    			padding: 0 60rpx;
    			color: grey;
    			text-indent: 2em;
    		}
    		.btn{
    			padding: 8rpx 0rpx;
    			width: 400rpx;
    			text-align: center;
    			background:  #FF8D1A;
    			border-radius: 8rpx;
    			font-size: 26rpx;
    			color: white;
    		}
    	}
    }
    </style>
    

     3. uniapp微信小程序中uniCloud处理云数据库登陆:

    在cloudfunctions-aliyun下创建ace-login/index.js文件。

    下载jwt-simple第三方库引入jwt.js。

    在ace-login/index.js中:

    const crypto = require('crypto') //node自带模块
    const jwt = require('./jwt.js')  //引入jwt-simple中的
    const loginConfig = {
      AppId: '', //微信小程序AppId
      AppSecret: '' //微信小程序AppSecret
    }
    const passSecret = 'abc' //用于用户数据库密码加密的密钥,使用一个比较长的随机字符串即可
    const tokenExp = 8000000
    const db = uniCloud.database()
    exports.main = async (event, context) => {
    	let data = {
    	  appid: loginConfig.AppId,
    	  secret: loginConfig.AppSecret,
    	  js_code: event.code,
    	  grant_type: 'authorization_code'
    	}
    	const res = await uniCloud.httpclient.request('https://api.weixin.qq.com/sns/jscode2session', {  //向微信发送请求获取用户openId
    	  method: 'GET',
    	  data,
    	  dataType: 'json'
    	})
    	
    	const success = res.status === 200 && res.data && res.data.openid
    	if (!success) {
    	  return {
    	    status: -2,
    	    msg: '从微信获取登录信息失败'
    	  }
    	}
    	const {
    	  openid
    	} = res.data
    	let openidObj = {
    	  openid
    	}
    	const userInfo = event.userInfo
    	let tokenSecret = crypto.randomBytes(16).toString('hex'),
    	  token = jwt.encode(openidObj, tokenSecret)
    	const userInDB = await db.collection('ace-user').where({
    	  openid
    	}).get()
    	
    	let userUpdateResult
    	if (userInDB.data && userInDB.data.length === 0) {
    	  userUpdateResult = await db.collection('ace-user').add({  //没有该用户就新增
    	    ...openidObj,
    		...userInfo,
    	    tokenSecret,
    	    exp: Date.now() + tokenExp
    	  })
    	} else {
    	  userUpdateResult = await db.collection('ace-user').doc(userInDB.data[0]._id).set({  //有该用户就修改
    	    ...openidObj,
    		...userInfo,
    	    tokenSecret,
    	    exp: Date.now() + tokenExp
    	  })
    	}
    	
    	if (userUpdateResult.id || userUpdateResult.updated === 1) {
    		const userVal = await db.collection('ace-user').where({
    		  openid
    		}).get()
    		return {
    			status: 1,
    			token,
    			userInfo:userVal.data[0], //该用户的信息
    			msg: '登录成功'
    		}
    	}
    	
    	return {
    	  status: -1,
    	  msg: '微信登录'
    	}
    }
    
    

     

     

     

     

     

     

     

     

     

     

    展开全文
  • Android 一套完整的 Socket 解决方案

    千次阅读 2017-11-30 20:59:10
    Android 一套完整的 Socket 解决方案项目地址,喜欢点一个 star:AndroidSocket在前面:在上上周的时候,了一篇文章:在 Android 上,一个完整的 UDP 通信模块应该是怎样的?文中介绍了在 Android 端,一个完整...

    Android 一套完整的 Socket 解决方案

    项目地址,喜欢点一个 star:

    AndroidSocket

    写在前面:

    在上上周的时候,写了一篇文章:

    在 Android 上,一个完整的 UDP 通信模块应该是怎样的?

    文中介绍了在 Android 端,一个完整的 UDP 模块应该考虑哪些方面。当然了文中最后也提到了,UDP 的使用本身就有一些局限性,比如发送数据的大小有限制,属于不可靠协议,可能丢包。而且它是一对多发送的协议等等…如果能将这个模块能加入 TCP Socket 补充,那就比较完美解决了 Android 上端到端的通信。下面就来看看怎么去做。

    整体步骤流程

    先来说一下整体的步骤思路吧:

    1. 发送 UDP 广播,大家都知道 UDP 广播的特性是整个网段的设备都可以收到这个消息。
    2. 接收方收到了 UDP 的广播,将自己的 ip 地址,和双方约定的端口号,回复给 UDP 的发送方。
    3. 发送方拿到了对方的 ip 地址以及端口号,就可以发起 TCP 请求了,建立 TCP 连接。
    4. 保持一个 TCP 心跳,如果发现对方不在了,超时重复 1 步骤,重新建立联系。

    整体的步骤就和上述的一样,下面用代码展开:

    搭建 UDP 模块

        public UDPSocket(Context context) {
    
            this.mContext = context;
    
            int cpuNumbers = Runtime.getRuntime().availableProcessors();
            // 根据CPU数目初始化线程池
            mThreadPool = Executors.newFixedThreadPool(cpuNumbers * Config.POOL_SIZE);
            // 记录创建对象时的时间
            lastReceiveTime = System.currentTimeMillis();
    
            messageReceiveList = new ArrayList<>();
    
            Log.d(TAG, "创建 UDP 对象");
    //        createUser();
        }

    首先进行一些初始化操作,准备线程池,记录对象初始的时间等等。

        public void startUDPSocket() {
            if (client != null) return;
            try {
                // 表明这个 Socket 在设置的端口上监听数据。
                client = new DatagramSocket(CLIENT_PORT);
                client.setReuseAddress(true);
                if (receivePacket == null) {
                    // 创建接受数据的 packet
                    receivePacket = new DatagramPacket(receiveByte, BUFFER_LENGTH);
                }
    
                startSocketThread();
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }

    紧接着就创建了真正的一个 UDP Socket 端,DatagramSocket,注意这里传入的端口号 CLIENT_PORT 的意思是这个 DatagramSocket 在此端口号接收消息。

        /**
         * 开启发送数据的线程
         */
        private void startSocketThread() {
            clientThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    receiveMessage();
                }
            });
            isThreadRunning = true;
            clientThread.start();
            Log.d(TAG, "开启 UDP 数据接收线程");
    
            startHeartbeatTimer();
        }

    我们都知道 Socket 中要处理数据的发送和接收,并且发送和接收都是阻塞的,应该放在子线程中,这里就开启了一个线程,来处理接收到的 UDP 消息(UDP 模块上一篇文章讲得比较详细了,所以这里就不详细展开了)

        /**
         * 处理接受到的消息
         */
        private void receiveMessage() {
            while (isThreadRunning) {
                try {
                    if (client != null) {
                        client.receive(receivePacket);
                    }
                    lastReceiveTime = System.currentTimeMillis();
                    Log.d(TAG, "receive packet success...");
                } catch (IOException e) {
                    Log.e(TAG, "UDP数据包接收失败!线程停止");
                    stopUDPSocket();
                    e.printStackTrace();
                    return;
                }
    
                if (receivePacket == null || receivePacket.getLength() == 0) {
                    Log.e(TAG, "无法接收UDP数据或者接收到的UDP数据为空");
                    continue;
                }
    
                String strReceive = new String(receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength());
                Log.d(TAG, strReceive + " from " + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
    
                //解析接收到的 json 信息
                notifyMessageReceive(strReceive);
                // 每次接收完UDP数据后,重置长度。否则可能会导致下次收到数据包被截断。
                if (receivePacket != null) {
                    receivePacket.setLength(BUFFER_LENGTH);
                }
            }
        }

    在子线程接收 UDP 数据,并且 notifyMessageReceive 方法通过接口来向外通知消息。

        /**
         * 发送心跳包
         *
         * @param message
         */
        public void sendMessage(final String message) {
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        BROADCAST_IP = WifiUtil.getBroadcastAddress();
                        Log.d(TAG, "BROADCAST_IP:" + BROADCAST_IP);
                        InetAddress targetAddress = InetAddress.getByName(BROADCAST_IP);
    
                        DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), targetAddress, CLIENT_PORT);
    
                        client.send(packet);
    
                        // 数据发送事件
                        Log.d(TAG, "数据发送成功");
    
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
            });
        }

    接着 startHeartbeatTimer 开启一个心跳线程,每间隔五秒,就去广播一个 UDP 消息。注意这里 getBroadcastAddress 是获取的网段 ip,发送这个 UDP 消息的时候,整个网段的所有设备都可以接收到。

    到此为止,我们发送端的 UDP 算是搭建完成了。

    搭建 TCP 模块

    接下来 TCP 模块该出场了,UDP 发送心跳广播的目的就是找到对应设备的 ip 地址和约定好的端口,所以在 UDP 数据的接收方法里:

        /**
         * 处理 udp 收到的消息
         *
         * @param message
         */
        private void handleUdpMessage(String message) {
            try {
                JSONObject jsonObject = new JSONObject(message);
                String ip = jsonObject.optString(Config.TCP_IP);
                String port = jsonObject.optString(Config.TCP_PORT);
                if (!TextUtils.isEmpty(ip) && !TextUtils.isEmpty(port)) {
                    startTcpConnection(ip, port);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    这个方法的目的就是取到对方 UDPServer 端,发给我的 UDP 消息,将它的 ip 地址告诉了我,以及我们提前约定好的端口号。

    怎么获得一个设备的 ip 呢?

        public String getLocalIPAddress() {
            WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
            return intToIp(wifiInfo.getIpAddress());
        }
        private static String intToIp(int i) {
            return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "."
                    + ((i >> 24) & 0xFF);
        }

    现在拿到了对方的 ip,以及约定好的端口号,终于可以开启一个 TCP 客户端了。

        private boolean startTcpConnection(final String ip, final int port) {
            try {
                if (mSocket == null) {
                    mSocket = new Socket(ip, port);
                    mSocket.setKeepAlive(true);
                    mSocket.setTcpNoDelay(true);
                    mSocket.setReuseAddress(true);
                }
                InputStream is = mSocket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                OutputStream os = mSocket.getOutputStream();
                pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)), true);
                Log.d(TAG, "tcp 创建成功...");
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

    当 TCP 客户端成功建立的时候,我们就可以通过 TCP Socket 来发送和接收消息了。

    细节处理

    接下来就是一些细节处理了,比如我们的 UDP 心跳,当 TCP 建立成功之时,我们要停止 UDP 的心跳:

                    if (startTcpConnection(ip, Integer.valueOf(port))) {// 尝试建立 TCP 连接
                        if (mListener != null) {
                            mListener.onSuccess();
                        }
                        startReceiveTcpThread();
                        startHeartbeatTimer();
                    } else {
                        if (mListener != null) {
                            mListener.onFailed(Config.ErrorCode.CREATE_TCP_ERROR);
                        }
                    }
    
                // TCP已经成功建立连接,停止 UDP 的心跳包。
                public void stopHeartbeatTimer() {
                    if (timer != null) {
                        timer.exit();
                        timer = null;
                    }
        }

    对 TCP 连接进行心跳保护:

        /**
         * 启动心跳
         */
        private void startHeartbeatTimer() {
            if (timer == null) {
                timer = new HeartbeatTimer();
            }
            timer.setOnScheduleListener(new HeartbeatTimer.OnScheduleListener() {
                @Override
                public void onSchedule() {
                    Log.d(TAG, "timer is onSchedule...");
                    long duration = System.currentTimeMillis() - lastReceiveTime;
                    Log.d(TAG, "duration:" + duration);
                    if (duration > TIME_OUT) {//若超过十五秒都没收到我的心跳包,则认为对方不在线。
                        Log.d(TAG, "tcp ping 超时,对方已经下线");
                        stopTcpConnection();
                        if (mListener != null) {
                            mListener.onFailed(Config.ErrorCode.PING_TCP_TIMEOUT);
                        }
                    } else if (duration > HEARTBEAT_MESSAGE_DURATION) {//若超过两秒他没收到我的心跳包,则重新发一个。
                        JSONObject jsonObject = new JSONObject();
                        try {
                            jsonObject.put(Config.MSG, Config.PING);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        sendTcpMessage(jsonObject.toString());
                    }
                }
    
            });
            timer.startTimer(0, 1000 * 2);
        }

    首先会每隔两秒,就给对方发送一个 ping 包,看看对面在不在,如果超过 15 秒还没有回复我,那就说明对方掉线了,关闭我这边的 TCP 端。进入 onFailed 方法。

                    @Override
                    public void onFailed(int errorCode) {// tcp 异常处理
                        switch (errorCode) {
                            case Config.ErrorCode.CREATE_TCP_ERROR:
                                break;
                            case Config.ErrorCode.PING_TCP_TIMEOUT:
                                udpSocket.startHeartbeatTimer();
                                tcpSocket = null;
                                break;
                        }
                    }

    当 TCP 连接超时,我就会重新启动 UDP 的广播心跳,寻找等待连接的设备。进入下一个步骤循环。

    对于数据传输的格式啊等等细节,这个和业务相关。自己来定就好。

    还可以根据自己业务的模式,是 CPU 密集型啊,还是 IO 密集型啊,来开启不同的线程通道。这个就涉及线程的知识了。

    项目地址,喜欢点一个 star:

    AndroidSocket

    展开全文
  • 一套完整的后台管理系统

    千次阅读 2021-03-07 00:11:08
    前言这套Base Admin是一套简单通用的后台管理系统,主要功能有:权限管理、菜单管理、用户管理,系统设置、实时日志,实时监控,API加密,以及登录用户修改密码、配置个性菜单等。技术栈前...
  • 我个人从2016年就开始在做区块链系统开发的相关工作,最近身边很多朋友都在找我,想让我给他们讲讲区块链技术开发的相关知识,介于此,索性我就手撸了一套简单的java区块链系统,并了一份详细的开发教程,发布到...
  • 自动产生一套完全ASP程序,应该比较好用,可以帮助asp的代码,增加,修改,删除都可以的,是完整程序,对程序员哟帮助!!
  • 如何快速搭建一套完整的网络直播平台

    万次阅读 多人点赞 2017-01-13 10:31:35
    由于朋友公司的老总拿到了一大笔投资,准备搭建自己的旅游直播平台,本人作为流媒体技术方面的码农被应招入伍并被委以重任,带领团队打造一套自己的网络直播平台。 经过几个月的战斗最近终于完
  • 基于Java开发一套完整的区块链系统(附源码)

    千次阅读 多人点赞 2021-01-15 16:30:00
    我个人从2016年就开始在做区块链系统开发的相关工作,最近身边很多朋友都在找我,想让我给他们讲讲区块链技术开发的相关知识,介于此,索性我就手撸了一套简单的java区块链系统,并了一份详细的开发教程,发布到...
  • 来源:cnblogs.com/huanzi-qch/p/11534203.html作者:huanzi-qch前言这是一套简单通用的后台管理系统,主要功能有:权限管理、菜单管理、用户管理,...
  • 3 总结一套合理的、可操作的、适合公司现实情况的性能测试方案,为后续的性能测试工作提供基本思路 1.5 测试项目开发规范 1 在具体项目解决方案中添加测试项目 2 为每个模块建立各自的文件夹 ...
  • 现在热部署后刷新页面即可) 4、好多人都不知道,项目有工具类CodeDOM.java可以生成一套单表的完整增删改查后台代码。 配置好数据库,指定代码生成父位置。 运行main函数即可一键生成一套单表增删改查后台代码。 ...
  • UserDao数据库操作类继承了我们上一章所编写的MongodbBaseDao抽象实现类,大家通过看下面的代码会发现,实际上我们并没有多少代码,但是我们已经实现了用户的增删改查等这些通用的功能。 package ...
  • 细心的朋友一定在上一章节的程序运行中发现了这样的一个报错:  这个报错的造成是因为在大家访问首页的时候,我前端开启了websocket的连接,但是我们的后端并没有对websocket进行相应的支持,因此本章将教大家...
  • 其中/home/tony/nginx-1.8.0/sbin/nginx表示启动程序,这里用全路径更加直观,可以根据自己的习惯做软链接到系统路径。 (题外话 如何重启nginx 需要先kill了进程 ps -ef|grep nginx ps kill -9 进程号) (题外话 ...
  • 由于深入bootstrap的话那就是要一个专题来讲解了,此处主要讲解的是如何基于bootstrap来搭建一套完整的权限架构因此就不再此处深入的去讲解该框架,只要大家跑过一遍代码可以懂得如何使用就好了,若像更深入的去学习...
  • 该页面就是我们的swagger的页面,但是该页面上很明显是没有显示接口,那是因为我们到现在还没开始我们的controller层的接口,因此此处就没有显示相应的接口,接下来我们在我们的sys包底下创建一个controller包同时...
  • 一套完整的技术框架

    万次阅读 2011-12-09 14:16:34
    一套完整的技术框架 转载自http://blog.csdn.net/phenixiii/article/month/2007/11 1 引言 1.1 前言 本文将基于目前现有的软件开发架构(以下简称‘架构’)(Packer for Delphi),同时如何合理地引进新技术...
  • 现在热部署后刷新页面即可) 4、好多人都不知道,项目有工具类CodeDOM.java可以生成一套单表的完整增删改查后台代码。 配置好数据库,指定代码生成父位置。 运行main函数即可一键生成一套单表增删改查后台代码。 ...
  • 现在热部署后刷新页面即可) 4、好多人都不知道,项目有工具类CodeDOM.java可以生成一套单表的完整增删改查后台代码。 配置好数据库,指定代码生成父位置。 运行main函数即可一键生成一套单表增删改查后台代码。 ...
  • 据库连接池参考:如何自己手写一套数据库连接池? 完整代码结构如下 1.原生mybatis 1.1.原生mybatis的使用 定义一个mapper public interface UserMapper { @Select("select * from user where userName = #{userName...
  • Lin UI 是由林间有风团队精心打造的一套微信小程序组件库,组件丰富、设计优美,并且拥有完整的商业案例,是您开发微信小程序的不二选择。 官方文档 Github 链接 码云 Gitee 链接 林间有风团队...
  • uniapp一套代码开发app和微信小程序

    千次阅读 2020-07-02 15:35:55
    1、uniapp对于独自开发是相当友好的,一套代码可以兼容app(安卓,ios),小程序,h5等,一定程度上降低了开发的成本,个人开发的压力也在某种程度上减小了。 2、uniapp语法,如果开发人员有一定的前端基础,并且对...
  • (三)一个完整的Linux驱动程序访问硬件并应用程序进行测试1. Linux设备驱动的分类2. Linux字符设备驱动框架1). 设备号2).字符设备操作集合 -- file_operations结构体 本系列导航 (一)初识Linux驱动 (二)...
  • 程序员请照顾好自己,周末病魔差点一套带走我。

    万次阅读 多人点赞 2019-12-22 21:18:37
    一套流程丝毫不拖泥带水。 是的不知道抽了几次血,抽一次还要抽几管那种,不过为了确保病情这一切都是值得的。 感触最大的就是做心电图的时候,躺在病床上,医生把冰冷的仪器放在你的身上,当时我就多想了,把那想成...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 126,075
精华内容 50,430
热门标签
关键字:

如何写一套完整的程序