[置顶] 自己动手编写仿QQ的app -1注册界面by sdust iot zhl
2016-08-18 20:01
465 查看
协议:tcp/ip 协议
架构:c/s 架构
数据库:mysql
服务器端接口语言 :python
客户端语言:安卓
注册:服务器端创建套接字,获取客户端发来的json数据,解析完后存入数据库
首先安装服务器端mysql 数据库 ,这里我直接安装了 phpstudy
然后 进入cmd,mysql - u root - p 输入密码登录数据库
然后进入 test 数据库
创建如下的数据表
即创建了一个 主键为id 拥有两个栏目,account (账户)与password(密码)的表用于储存用户账户密码,并且设置各栏目非空,主键自增,account(账户)键值唯一,即用户名唯一
然后开始编写服务器端代码
其中
dict=json.loads(data)
dict = eval(dict)
是将json数据流转化为string,再转化为dict ,从而接下来对其进行操作
而conne=MySQLdb.connect(host=’127.0.0.1’,user=’root’,passwd=’ONS2015’,db=’test’,port=3306)
是数据库连接操作
sql = ” INSERT INTO users (account,password) VALUES(%s,%s)”;
cur.execute(sql,tuple)
则是向数据库中插入数据的操作
客户端先使用 python 进行简单测试,代码如下:
主要使用了d=json.dumps(dict)将dict转化为json字符串
服务器端输出如下:
客户端如下:
接下来开始写安卓端的界面,这是第一次做出来的效果图
其中UI,即xml文件上遇到的问题如下:
1.密码输入只以 * 显示
2.设置一个隐藏的提示功能的文本
3.限制输入只能为字母数字下划线
以及长度限制最高为10
4.设置隐藏的提示框,即设置一个字体颜色,内容为空的textview ,用于在接下来提示输入
从中获得了很多学习经验,
如:控件可以嵌套LinearLayout,从而形成各种风格的布局
字体大小要设置为sp单位
可以设置RadioGroup 管理RadioButton
这是最终的客户端代码
这是最终的修改过后的服务器端代码
这是最终效果图:
1.未填完整信息
2.输入信息不正确
3.网络连接超时
4存在相同用户名.
5,注册成功
架构:c/s 架构
数据库:mysql
服务器端接口语言 :python
客户端语言:安卓
注册:服务器端创建套接字,获取客户端发来的json数据,解析完后存入数据库
首先安装服务器端mysql 数据库 ,这里我直接安装了 phpstudy
然后 进入cmd,mysql - u root - p 输入密码登录数据库
然后进入 test 数据库
创建如下的数据表
mysql> create table users ( -> `id` int not null auto_increment , -> `account` char(10) not null, -> `password` char(10) not null, -> primary key (`id`), -> unique key( `account`) -> );
即创建了一个 主键为id 拥有两个栏目,account (账户)与password(密码)的表用于储存用户账户密码,并且设置各栏目非空,主键自增,account(账户)键值唯一,即用户名唯一
然后开始编写服务器端代码
#coding:utf-8 import MySQLdb ,socket,threading ,time,json from json import * class myThread (threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): print "Starting " + self.name try: data=conn.recv(1024) print data dict=json.loads(data) dict = eval(dict) threadLock.acquire() cur=conne.cursor() account=dict['account'] password = dict['password'] tuple = (account,password) sql = " INSERT INTO users (account,password) VALUES(%s,%s)"; cur.execute(sql,tuple) conn.send("写入成功") cur.close() print("succeed in writing") threadLock.release() finally: conn.close() conne=MySQLdb.connect(host='127.0.0.1',user='root',passwd='ONS2015',db='test',port=3306) threadLock = threading.Lock() HOST='127.0.0.1' PORT=2333 s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(('127.0.0.1',2333)) s.listen(5) while (1): conn,addr = s.accept() print'Connected by',addr # 接受客户端端的连接后,就开启一个线程处理客户端的数据 thread = myThread() thread.start()
其中
dict=json.loads(data)
dict = eval(dict)
是将json数据流转化为string,再转化为dict ,从而接下来对其进行操作
而conne=MySQLdb.connect(host=’127.0.0.1’,user=’root’,passwd=’ONS2015’,db=’test’,port=3306)
是数据库连接操作
sql = ” INSERT INTO users (account,password) VALUES(%s,%s)”;
cur.execute(sql,tuple)
则是向数据库中插入数据的操作
客户端先使用 python 进行简单测试,代码如下:
import MySQLdb ,socket,threading ,time,json from json import * HOST='127.0.0.1' PORT=2333 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('127.0.0.1',2333)) dict="{'account':'doge','password':'123'}" d=json.dumps(dict) s.sendall(d) data=s.recv(1024) print data
主要使用了d=json.dumps(dict)将dict转化为json字符串
服务器端输出如下:
C:\Python27\python.exe E:/代码文件/python/client_test.py Connected by ('127.0.0.1', 59171) Starting Thread-1 "{'account':'doge','password':'123'}" succeed in writing
客户端如下:
C:\Python27\python.exe E:/代码文件/python/client.py 写入成功 Process finished with exit code 0
接下来开始写安卓端的界面,这是第一次做出来的效果图
其中UI,即xml文件上遇到的问题如下:
1.密码输入只以 * 显示
android:inputType="textPassword"
2.设置一个隐藏的提示功能的文本
android:hint="请输入账户"
3.限制输入只能为字母数字下划线
以及长度限制最高为10
android:digits="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_" android:maxLength="10"
4.设置隐藏的提示框,即设置一个字体颜色,内容为空的textview ,用于在接下来提示输入
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#f4f4f3" android:orientation="vertical"> <ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:contentDescription="dp" android:src="@mipmap/dp" android:layout_weight="0.15"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.05" android:orientation="horizontal" > <TextView android:layout_width="0sp" android:layout_height="match_parent" android:text="账户" android:id="@+id/register_tv1" android:layout_weight="0.02" android:gravity="center" android:textSize="20sp" /> <EditText android:layout_width="0sp" android:layout_height="match_parent" android:hint="请输入账户" android:id="@+id/register_account" android:layout_weight="0.07" android:digits="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_" android:maxLength="10" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/register_warm1" android:text="" android:layout_weight="0.0005" android:gravity="center" android:textSize="20sp" android:textColor="#fc4984" android:visibility="visible" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.05" android:orientation="horizontal" > <TextView android:layout_width="0sp" android:layout_height="match_parent" android:text="密码" android:id="@+id/register_tv2" android:layout_weight="0.02" android:gravity="center" android:textSize="20sp" /> <EditText android:layout_width="0sp" android:layout_height="match_parent" android:hint="请输入密码" android:id="@+id/register_password1" android:layout_weight="0.07" android:inputType="textPassword" android:digits="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_" android:maxLength="10" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:id="@+id/register_warm2" android:layout_weight="0.0005" android:gravity="center" android:textSize="20sp" android:textColor="#fc4984" android:visibility="visible" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.05" android:orientation="horizontal" > <TextView android:layout_width="0sp" android:layout_height="match_parent" android:text="密码" android:id="@+id/register_tv3" android:layout_weight="0.02" android:gravity="center" android:textSize="20sp" /> <EditText android:layout_width="0sp" android:layout_height="match_parent" android:hint="请再次输入密码" android:id="@+id/register_password2" android:layout_weight="0.07" android:inputType="textPassword" android:digits="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_" android:maxLength="10" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:id="@+id/register_warm3" android:layout_weight="0.0005" android:gravity="center" android:textSize="20sp" android:textColor="#fc4984" android:visibility="visible" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.05" android:orientation="horizontal" > <TextView android:layout_width="0sp" android:layout_height="wrap_content" android:text="性别" android:textSize="20sp" android:gravity="center" android:layout_weight="0.29"/> <RadioGroup android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.7"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男" android:layout_weight="0.5"/> <RadioButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" android:layout_weight="0.5"/> </LinearLayout> </RadioGroup> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.1" android:orientation="horizontal" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:text="完成注册" android:id="@+id/register_bt" android:layout_weight="0.005" android:background="#1fb2f6" android:textColor="#fefefe" android:textSize="20sp" /> </LinearLayout> </LinearLayout>
从中获得了很多学习经验,
如:控件可以嵌套LinearLayout,从而形成各种风格的布局
字体大小要设置为sp单位
可以设置RadioGroup 管理RadioButton
这是最终的客户端代码
package doge.dp.test; import android.os.Bundle; import android.os.Looper; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.NavigationView; import android.support.design.widget.Snackbar; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); SetListener(); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); if (id == R.id.nav_camera) { // Handle the camera action } else if (id == R.id.nav_gallery) { } else if (id == R.id.nav_slideshow) { } else if (id == R.id.nav_manage) { } else if (id == R.id.nav_share) { } else if (id == R.id.nav_send) { } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } //注册按钮响应事件 public void SetListener() { //定义控件变量 final EditText register_account = (EditText) findViewById(R.id.register_account); final EditText register_password1 = (EditText) findViewById(R.id.register_password1); final EditText register_password2 = (EditText) findViewById(R.id.register_password2); final TextView register_warm1 = (TextView) findViewById(R.id.register_warm1); final TextView register_warm2 = (TextView) findViewById(R.id.register_warm2); final TextView register_warm3 = (TextView) findViewById(R.id.register_warm3); //设置按钮点击监听 Button register_bt = (Button) findViewById(R.id.register_bt); TextWatcher textWatcher1 = new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void afterTextChanged(Editable s) { String register_account_text = register_account.getText().toString(); if(s.length()<6||s.length()>10) { register_warm1.setText("请将账号长度控制在6-10位之间"); } else register_warm1.setText(""); } }; register_account.addTextChangedListener(textWatcher1); TextWatcher textWatcher2 = new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void afterTextChanged(Editable s) { String register_password1_text = register_password1.getText().toString(); String register_password2_text = register_password2.getText().toString(); if(register_password1_text.length()<6||register_password1_text.length()>10) { register_warm2.setText("请将密码长度控制在6-10位之间"); } else register_warm2.setText(""); if(!register_password2_text.equals(register_password1_text)) register_warm3.setText("请输入一样的密码"); else register_warm3.setText(""); } }; register_password1.addTextChangedListener(textWatcher2); TextWatcher textWatcher3 = new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void afterTextChanged(Editable s) { String register_password2_text = register_password2.getText().toString(); String register_password1_text = register_password1.getText().toString(); if(!register_password2_text.equals(register_password1_text)) { register_warm3.setText("请输入一样的密码"); } else register_warm3.setText(""); } }; register_password2.addTextChangedListener(textWatcher3); Button reister_bt = (Button) findViewById(R.id.register_bt); reister_bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String register_password1_text = register_password1.getText().toString(); String register_password2_text = register_password2.getText().toString(); String register_account_text = register_account.getText().toString(); String register_warm1_text = register_warm1.getText().toString(); String register_warm2_text = register_warm2.getText().toString(); String register_warm3_text = register_warm3.getText().toString(); if ( register_password1_text.equals("")||register_password2_text.equals("")||register_account_text.equals("") ) Toast.makeText( getApplicationContext(),"请输入完整注册信息",Toast.LENGTH_SHORT).show(); else if (!register_warm1_text.equals("")||!register_warm2_text.equals("")||!register_warm3_text.equals("")) Toast.makeText( getApplicationContext(),"请输入正确的注册信息",Toast.LENGTH_SHORT).show(); else { Toast.makeText(getApplicationContext(),"flag",Toast.LENGTH_LONG); ExecutorService exec = Executors.newCachedThreadPool(); MyTask task = new MyTask(); Future<Boolean> future = exec.submit(task); try { future.get(1, TimeUnit.SECONDS); } catch (InterruptedException e) { Toast.makeText(getApplicationContext(),"请求超时,请检查网络",Toast.LENGTH_LONG).show(); } catch (ExecutionException e) { Toast.makeText(getApplicationContext(),"请求超时,请检查网络",Toast.LENGTH_LONG).show(); } catch (TimeoutException e) { Toast.makeText(getApplicationContext(),"请求超时,请检查网络",Toast.LENGTH_LONG).show(); } finally { exec.shutdownNow(); } } } }); } //继承了callable接口 class MyTask implements Callable<Boolean> { String flag="0"; @Override public Boolean call() throws Exception { try { getMainLooper().prepare(); EditText register_account = (EditText) findViewById(R.id.register_account); EditText register_password1 = (EditText) findViewById(R.id.register_password1); EditText register_password2 = (EditText) findViewById(R.id.register_password2); String account = register_account.getText().toString(); String password = register_password1.getText().toString(); Socket socket = new Socket("10.0.2.2", 2333); OutputStream outputStream = socket.getOutputStream(); String jsonStr = "{\"account\": \""+ account +"\"," + " \"password\": \""+password+"\"}"; BufferedWriter BW = new BufferedWriter(new OutputStreamWriter(outputStream)); BW.write(jsonStr); BW.flush(); InputStream is=socket.getInputStream(); BufferedReader br=new BufferedReader(new InputStreamReader(is)); int data =br.read(); System.out.println(data); if(data==49) Toast.makeText(getApplicationContext(),"注册成功",Toast.LENGTH_LONG).show(); else Toast.makeText(getApplicationContext(),"已存在同名账户,请更换账户名",Toast.LENGTH_LONG).show(); socket.close(); flag="1"; getMainLooper().loop(); } catch (java.net.SocketTimeoutException e) { Toast.makeText(getApplicationContext(),"连接失败,请检查网络",Toast.LENGTH_LONG).show(); } catch (IOException e) { Toast.makeText(getApplicationContext(), "连接失败,请检查网络", Toast.LENGTH_LONG).show(); e.printStackTrace(); } return true; } } }
这是最终的修改过后的服务器端代码
#coding:utf-8 import MySQLdb ,socket,threading ,time,json from json import * class myThread (threading.Thread): def __init__(self): threading.Thread.__init__(self) #线程的主体代码 def run(self): print "Starting " + self.name try: data=conn.recv(1024) #接受数据 dict = eval(data) #强转为dict account=dict['account'] password = dict['password'] tuple = (account,password) sql = " INSERT INTO users (account,password) VALUES(%s,%s)"; threadLock.acquire() #获取线程锁 #接下来执行数据库操作 cur=conne.cursor() cur.execute(sql,tuple) #执行完毕后向客户端发1表示成功 conn.send("1") print("succeed in writing") except Exception,ex: conn.send("0") print("failed in writing") finally: cur.close() threadLock.release() conn.close() #连接数据库 conne=MySQLdb.connect(host='127.0.0.1',user='root',passwd='ONS2015',db='test',port=3306) threadLock = threading.Lock() HOST='127.0.0.1' PORT=2333 #创建socket s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(('127.0.0.1',2333)) #设置最高同时监听数 s.listen(1000) while (1): conn,addr = s.accept() # 接受客户端端的连接后,就开启一个线程处理客户端的数据 thread = myThread() thread.start()
这是最终效果图:
1.未填完整信息
2.输入信息不正确
3.网络连接超时
4存在相同用户名.
5,注册成功
相关文章推荐
- java 并发入门 by sdust iot zhl
- 自己动手编写devExpress组件自动安装程序
- 自己动手编写一个简单的U盘杀毒程序
- 自己动手编写Delphi Expert
- 自己动手编写启动JAVA程序的EXE文件
- 自己动手去QQ聊天窗口左下角文字链接广告
- 自己动手编写Eclipse扩展点
- 自己动手编写一个类似 QuickPart 的用户控件包装器
- 自己动手编写Eclipse扩展点
- [转]让自己编写的DLL加载到Slot1(by fllsoft)
- 自己动手制作WinXP登录界面
- 自己动手编写devExpress组件自动安装程序
- 自己动手编写Web服务解析工具
- 自己动手编写Web服务工具[解析]
- 自己动手做QQ(毕业设计)—p2p聊天工具(IM)源代码
- 自己动手编写组件
- 自己动手注册xde for .net帮助
- 自己动手编写 IronPython IDE
- 自己动手封装SDK界面库
- 自己动手编写一个类似 QuickPart 的用户控件包装器