【源码】c#编写的安卓客户端与Windows服务器程序进行网络通信
用c#开发安卓程序 (xamarin.android)系列之三
为了方便您测试,我临时搭建了一个服务器 您可以安装apk文件,直接测试 apk文件下载地址 (测试服务器将会运行至2015年3月1日)
通信框架为来自英国的NetworkComms2.3.1开源通信框架 序列化采用Protobuf.net开源框架
客户端界面如下:

服务器端程序界面:
服务器搭建在winserver2003 上,基于.net4.0.
数据库采用sql2005

输入数据:

数据库建设完成,打开VS2010开始,创建相关的工程

创建服务器端工程


下一步:打开CodeSmith创建“存储过程”,“数据层”代码,“逻辑层(Business层代码)”:
相关CodeSmith模板下载地址:
分享我所使用的数据库框架
使用的CodeSmith为6.5版本:

生成完成后,VS中工程图:

下一步先构建服务器代码
CREATE PROCEDURE [dbo].Users_SelectOneByUserName
@Name nvarchar()
AS
SELECT
ID,Name,PassWord
FROM
[dbo].[Users]
WHERE
[Name] = @Name
数据库中添加存储过程
DBUsers.CS中添加:
//添加 根据UserID获取用户
public static IDataReader GetOneByUserName(
string name)
{
SqlParameterHelper sph = );
sph.DefineSqlParameter(, ParameterDirection.Input, name);
return sph.ExecuteReader();
}
逻辑层DoUsers中添加:
public static string Login(string username, string password)
{
using (IDataReader reader = DBUsers.GetOneByUserName(username))
{
string theResult = "登录不成功";
Users theUser = PopulateFromReader(reader);
if (theUser == null)
{
theResult = "用户不存在";
}
else if (theUser.PassWord == password)
{
theResult = "登录成功";
}
else
{
theResult = "密码不正确";
}
return theResult;
}
}
服务器端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NetworkCommsDotNet;
using System.Net;
using Mobile.Business;
using Mobile.Entity;
namespace MobileServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//服务器开始监听客户端的请求
//开始监听某T端口
IPEndPoint thePoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
TCPConnection.StartListening(thePoint, false);
button1.Text = "监听中";
button1.Enabled = false;
//此方法中包含服务器具体的处理方法。
StartListening();
}
private void StartListening()
{
//禁用日志记录 服务器端正式使用时,禁用日志记录
NetworkComms.DisableLogging();
//处理登陆请求
NetworkComms.AppendGlobalIncomingPacketHandler<Users>("UserLogin", IncomingLoginRequest);
}
//处理某个具体的请求
private void IncomingLoginRequest(PacketHeader header, Connection connection, Users currentUser)
{
try
{
//从数据库中获取返回结果
string resMsg = DoUsers.Login(currentUser.Name,currentUser.PassWord);
ResMessage contract = new ResMessage();
contract.Message = resMsg;
//把结果返回给客户端
connection.SendObject("ResLogin", contract);
}
catch (Exception ex)
{
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
NetworkComms.Shutdown();
this.Dispose();
this.Close();
}
}
}
至此,我们已经完成了“建设数据库”,“建表”,“生成数据库存储过程“,”数据层代码“,”逻辑层代码“,”服务器端代码的编写“。只剩下安卓客户端的编写了。
借助xamarin平台,用C#语言开发安卓程序,最大的优势,个人感觉是可以使用.net平台上众多优秀的库类,特别是通过稳定成熟的通信框架与c#服务器端进行交互。


修改 Main.axml文件,增加几个文本框给用户输入用户名和密码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/ConnectButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="连接服务器" />
<TextView
android:id="@+id/tvUseName"
android:layout_width="195px"
android:layout_height="35px"
android:text="用户名:" />
<EditText
android:id="@+id/etUserName"
android:layout_width="195px"
android:layout_height="wrap_content"
android:text=""
android:textSize="18sp" />
<TextView
android:id="@+id/tvPassWord"
android:layout_width="195px"
android:layout_height="35px"
android:text="密码:" />
<EditText
android:id="@+id/etPassWord"
android:layout_width="195px"
android:layout_height="wrap_content"
android:text=""
android:textSize="18sp" />
<Button
android:id="@+id/MyButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="登陆" />
<ScrollView
android:id="@+id/mainTextScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:layout_above="@+id/messageTextInput">
<TextView
android:id="@+id/mainText"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:inputType="none" />
</ScrollView>
</LinearLayout>
修改Main.axml文件
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using NetworkCommsDotNet;
using DPSBase;
using System.Net;
using Mobile.Entity;
namespace Mobile.Client
{
[Activity(Label = "Mobile.Client", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
;
//连接信息对象
public ConnectionInfo connInfo = null;
//连接对象
Connection newTcpConnection;
//连接服务器
Button connButton;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
//映射登陆按钮
Button button = FindViewById<Button>(Resource.Id.MyButton);
//登陆按钮相关的方法
button.Click += loginButton_Click;
//映射连接服务器按钮
connButton = FindViewById<Button>(Resource.Id.ConnectButton);
//连接服务器按钮相关方法
connButton.Click += connButton_Click;
//TextView 显示信息
tvShowMessage = FindViewById<TextView>(Resource.Id.mainText);
//映射输入用户名控件
etUserName = FindViewById<EditText>(Resource.Id.etUserName);
//映射输入密码控件
etPassWord = FindViewById<EditText>(Resource.Id.etPassWord);
if (NetConnected())
{
AppendMessage("网络状态:可用");
}
else
{
AppendMessage("无网络,请先设置网络");
}
}
//连接服务器相关方法
void connButton_Click(object sender, EventArgs e)
{
//给连接信息对象赋值
connInfo = new ConnectionInfo(ServerIP, ServerPort);
//如果不成功,会弹出异常信息
newTcpConnection = TCPConnection.GetConnection(connInfo);
connButton.Text = "连接成功";
connButton.Enabled = false;
}
string ServerIP = "115.28.141.108";
;
//客户端登陆相关方法
void loginButton_Click(object sender, EventArgs e)
{
Users theUser = new Users();
theUser.Name = etUserName.Text;
theUser.PassWord = etPassWord.Text;
ResMessage resMessage = newTcpConnection.SendReceiveObject<ResMessage>(, theUser);
if (resMessage.Message == "登陆成功")
AppendMessage("登陆成功");
else
//显示错误信息
AppendMessage(resMessage.Message);
}
//用于显示信息的TextView
TextView tvShowMessage;
//用户名
EditText etUserName;
//密码
EditText etPassWord;
/// <summary>
/// 数据序列化器
/// </summary>
public DataSerializer Serializer { get; set; }
//显示信息
public void AppendMessage(string message)
{
tvShowMessage.Text += System.Environment.NewLine + message;
}
//判断当前网络是否可用
private bool NetConnected()
{
var cm = Context.ConnectivityService;
var cmMgr = (Android.Net.ConnectivityManager)GetSystemService(cm);
if (cmMgr.GetNetworkInfo(Android.Net.ConnectivityType.Mobile).IsConnected || cmMgr.GetNetworkInfo(Android.Net.ConnectivityType.Wifi).IsConnected)
{
return true;
}
else
{
return false;
}
}
}
}
MainActivity代码
文章先写到这儿,希望您喜欢
www.networkcomms.cn
【源码】c#编写的安卓客户端与Windows服务器程序进行网络通信的更多相关文章
- 项目源码--Android即时通讯IM客户端
下载源码 技术要点: 1.完整精美客户端UI设计 2.自定义控件的灵活使用 3.UI控件的详细使用 4.即时通讯IM协议的实现 5.完整即时通讯IM客户端实现 6.源码详细的中文注释 ……. ...
- Netty源码分析第3章(客户端接入流程)---->第1节: 初始化NioSockectChannelConfig
Netty源码分析第三章: 客户端接入流程 概述: 之前的章节学习了server启动以及eventLoop相关的逻辑, eventLoop轮询到客户端接入事件之后是如何处理的?这一章我们循序渐进, 带 ...
- Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建
Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...
- Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建
Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...
- Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector
Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...
- Netty源码分析第3章(客户端接入流程)---->第5节: 监听读事件
Netty源码分析第三章: 客户端接入流程 第五节: 监听读事件 我们回到AbstractUnsafe的register0()方法: private void register0(ChannelPro ...
- Zookeeper 源码(三)Zookeeper 客户端源码
Zookeeper 源码(三)Zookeeper 客户端源码 Zookeeper 客户端主要有以下几个重要的组件.客户端会话创建可以分为三个阶段:一是初始化阶段.二是会话创建阶段.三是响应处理阶段. ...
- CentOS 7上源码编译安装和配置LNMP Web+phpMyAdmin服务器环境
CentOS 7上源码编译安装和配置LNMP Web+phpMyAdmin服务器环境 什么是LNMP? LNMP(别名LEMP)是指由Linux, Nginx, MySQL/MariaDB, PHP/ ...
- [源码解析] NVIDIA HugeCTR,GPU 版本参数服务器 --(1)
[源码解析] NVIDIA HugeCTR,GPU版本参数服务器 --(1) 目录 [源码解析] NVIDIA HugeCTR,GPU版本参数服务器 --(1) 0x00 摘要 0x01 背景 1.1 ...
随机推荐
- Java中String类的方法及说明
String : 字符串类型 一. String sc_sub = new String(c,3,2); // String sb_copy = new String(sb) ...
- HttpClient_002_中文乱码、HttpClient中文乱码透析、总结
中文乱码原理代码: String s = "中文"; byte[] bs2 = s.getBytes("utf-8");//将s拆成:utf-8个体,注:utf ...
- 关于学习Knockoutjs--入门(一)
前段时间做项目一直在用knockout,虽然用着不怎么利索,但是知识是一点一点探索的. 首先介绍一下 Knockout是什么? 他是一个很优秀的js库,他最大的功能就是实现双向绑定,它可以帮助你仅使用 ...
- python urllib2 支持 自定义cookie
先是在GOOGLE 上找了下, 发现就是只有2种方法,试了下,果然不行. 1, MozillaCookieJar 自定义保存到文件中 加载的时候不行,保存没问题. 2,opener.addheader ...
- Prince2的七大原则(7)
[Prince2科普]Prince2的七大原则(7) 2016-12-12 光环组织级项目管理 按照惯例我们先来回顾一下,PRINCE2七大原则分别是指:持续的业务验证,经验学习,角色与责任,按阶段管 ...
- 解决PowerDesigner 生成Sql2005-2012 找不到sysproperties表的问题
造成此问题的原因是由于Sql 2005 删除了系统表 sysproperties 而改用 sys.extended_properties 表所致 ,微软的目的不再去猜测网上有二种解决方式 但不符合本人 ...
- [课程设计]Scrum 2.2 多鱼点餐系统开发进度(下单页面修复&美化)
[课程设计]Scrum 2.2 多鱼点餐系统开发进度 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅到店点餐系统WEB ...
- tomcat域名访问配置
模拟线上环境,在本地以域名访问系统思路 1.首先在hosts文件将域名映射为本地IP 2.假如服务器80端口已被占用,可以用nginx转发,在nginx/vhosts/abc.com加入如下配置 se ...
- Android中Bitmap和Drawable
一.相关概念 1.Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable) ...
- 【20160924】GOCVHelper 图像处理部分(3)
//根据轮廓的圆的特性进行选择 vector<VP> selectShapeCircularity(Mat src,Mat& draw,vector<VP> c ...