最近两个月感觉还是学了不少东西,安卓了解更加透彻,web开发也能拿的出手,php也开始上手了。总会有不想写代码的时候,这时就来总结总结学习的东西也挺好的。
现在主要存在两种网络模式,B/S和C/S。相对于B/S,C/S可能要稍微复杂一点,需要我们开发客户端。C/S可以使用tcp/ip协议和http协议进行通信。我们从简单的开始,看一下手机客户端怎么用这两种方式连接后台验证密码成功登陆。
一、使用http协议
我们需要一个web服务器,至于这个服务器怎么搭建,用servlet+jdbc还是使用hibernate,spring这些框架都是可以实现的。这里我使用的是hibernate,新建一个web工程,hibernate配置文件代码如下:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.username">XXX</property>
<property name="hibernate.connection.password">XXX</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@ip:port:dataname</property>
<property name="show_sql">true</property>
<mapping resource="com/xyj/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.xyj.hibernate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import org.hibernate.Session;
import org.junit.Test;
import com.zifeiyu.domain.Score;
import com.zifeiyu.domain.Student;
/*
* 提供数据库的查询服务,包括密码
*/
public class DBService {
public static String getPassword(String username) {
Session session = null;
try {
session = hibOracleUtils.getSession();
String hql="from User as s where s.username=?";
Query query=session.createQuery(hql);
//填充占位符
query.setString(0, username);
User user=(User) query.uniqueResult();
return user.getpassword();
}finally {
if (session != null) {
session.close();
}
}
}
}
服务器类:
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
String username= req.getParameter("username");
String password = req.getParameter("password");
System.out.println("=========username========" + username);
System.out.println("=========password========" + password);
String PASSWD;
try {
//根据用户名从数据库取出密码(数据库中存放的是md5加密后的密码,客户端传过来的也是加密后的,保证了安全性)
PASSWD = DBService.getPassword(username);
if (password.equals(PASSWD)) {
pw.print(true);
} else {
pw.print(false);
}
} catch (Exception e) {
pw.print(false);
}
}
}
这样后台服务器就搭建好了(上面仅仅贴出了重要代码),再来看看手机客户端怎么发送http请求。
package com.xyj.login;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
public class HttpClientToServer {
String urlAddress = "http://localhost:8081/AndroidServer/login.do";
public HttpClientToServer(){
}
public String doPost(String USER_XH,String password){
HttpPost httpPost = new HttpPost(urlAddress);
List params = new ArrayList();
NameValuePair pair1 = new BasicNameValuePair("username", username);
NameValuePair pair2 = new BasicNameValuePair("password", password);
params.add(pair1);
params.add(pair2);
HttpEntity he;
try {
he = new UrlEncodedFormEntity(params, "gbk");
httpPost.setEntity(he);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
HttpClient hc = new DefaultHttpClient();
try {
HttpResponse ht = hc.execute(httpPost);
if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity het = ht.getEntity();
InputStream is = het.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();
//String str = EntityUtils.toString(he);
System.out.println("========="+response);
return response;
}else{
return "error";
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
}
}
然后根据返回值是TRUE或者FALSE自定义提示消息就行了。
二、使用tcp/ip协议
服务器端使用jdbc连接数据库,代码如下:
package myServer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class myServerSocket {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
// 监听8888端口
try {
serverSocket = new ServerSocket(8888);
System.out.println("服务器开启");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
// 有请求接入
socket = serverSocket.accept();
//开启线程处理请求
new serverThread(socket).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package myServer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mysql.jdbc.ResultSetMetaData;
public class serverThread extends Thread {
public Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
String[] arr;
// 用于连接数据库
static String DBDrive = "com.mysql.jdbc.Driver";
static String connStr = "jdbc:mysql://localhost:3306/mydb";
// 连接对象
static Connection conn = null;
// 语句对象
PreparedStatement statement = null;
// 查询结果对象
ResultSet resultSet = null;
public serverThread(Socket socket) {
this.socket = socket;
// 连接mysql数据库
linkMySql();
}
private void linkMySql() {
// 加载数据库驱动程序
try {
Class.forName(DBDrive);
System.out.println("驱动成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connStr, "XXX", "XXX");
System.out.println("连接成功");
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
try {
dataInputStream = new DataInputStream(socket.getInputStream());
// 读取消息
String msg = dataInputStream.readUTF();
arr = msg.split(" ");
System.out.println(msg);
// 响应请求
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
try {
checkInfo();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
// 关闭相关的流
try {
if (dataInputStream != null)
dataInputStream.close();
if (dataOutputStream != null)
dataOutputStream.close();
if (socket != null)
socket.close();
if(conn!=null)
conn.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void checkInfo() throws SQLException {
String sql="select * from user where username=?";
List<Object> params=new ArrayList<Object>();
params.add(arr[0]);
//得到该用户的所有信息
Map<String, Object> map=findSimpleResult(sql,params);
//输出
System.out.println(map);
//通过键值得到密码
String psd=(String) map.get("psd");
if(psd==null){
try {
dataOutputStream.writeUTF("该用户不存在");
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
if(psd!=null&&psd.equals(arr[1]))
dataOutputStream.writeUTF("登录成功");
else
dataOutputStream.writeUTF("密码有误");
} catch (IOException e) {
e.printStackTrace();
}
}
}
//通过用户名得到该用户的所有信息
private Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException {
Map<String, Object> map=new HashMap<String,Object>();
int index=1;
statement = conn.prepareStatement(sql);
if(params!=null&&!params.isEmpty()){
for(int i=0;i<params.size();i++){
statement.setObject(index++, params.get(i));
}
}
resultSet=statement.executeQuery();
java.sql.ResultSetMetaData metaData=resultSet.getMetaData();
int col_len=metaData.getColumnCount();
while(resultSet.next()){
for(int i=0;i<col_len;i++){
String col_name=metaData.getColumnName(i+1);
Object col_value=resultSet.getObject(col_name);
if(col_value==null){
col_value="";
}
map.put(col_name, col_value);
}
}
return map;
}
}
客户端代码:
package com.xyj.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import com.xyj.help.config;
import android.os.Handler;
import android.os.Message;
public class loginclientThread extends Thread {
private String name;
private String psd;
Handler handler;
String response;
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
public loginclientThread(String name, String psd, Handler handler) {
this.name = name;
this.psd = psd;
this.handler = handler;
}
public void run() {
// 创建套接字
try {
socket = new Socket("122.207.54.5", 8888);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
// 发送请求
dataOutputStream.writeUTF(toString());
// 得到返回消息
response = dataInputStream.readUTF();
Message message = Message.obtain();
message.what = config.islogin;
message.obj = response;
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataInputStream.close();
dataOutputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
//需要传送的参数多建议采用json传递
return name + " " + psd + " ";
}
}
以上就是这两种协议通信的主要代码。每天进步一点点,我们都可以非常棒
分享到:
相关推荐
在本文中,我们将深入探讨如何使用Qt框架实现一个基于客户端/服务器端的登录验证系统,其中数据传输使用MD5加密,以及与MySQL数据库的交互。首先,我们要理解C/S架构,即客户端-服务器架构,它是分布式应用的基础,...
Oracle客户端连接服务器端涉及到几个关键配置文件:listener.ora、sqlnet.ora和tnsnames.ora,它们都位于$ORACLE_HOME\network\admin目录下。理解这些文件的作用对于建立和维护Oracle数据库连接至关重要。 首先,`...
"客户端连接服务器并发送数据测试.rar"是一个专为服务器协议测试设计的工具,它允许我们模拟客户端行为,向服务器发送数据并接收响应,以确保服务器的数据处理能力正常运作。这个压缩包中的"MFCApplication3"很可能...
本示例是关于如何使用JBuilder2005这个集成开发环境(IDE)来实现用户登录的客户端和服务器端验证。对于JSP初学者而言,这是一个非常基础但重要的实践项目。 首先,客户端验证通常指的是在用户输入数据(如用户名和...
Socket是网络通信的基础,它提供了进程间通信的接口,使得FTP客户端可以通过创建Socket连接到FTP服务器,进行数据交换。 FTP客户端的工作流程大致如下: 1. 建立连接:客户端通过Socket创建TCP连接到服务器的21号...
在本文中,我们将深入探讨如何使用Android Studio开发客户端应用程序,以连接到运行在Delphi XE上的REST DataSnap服务器。REST(Representational State Transfer)是一种轻量级的、基于HTTP的架构风格,常用于...
在TCP通信中,客户端首先发起连接请求,服务器响应并建立连接,然后双方才能进行数据交换。这一过程通常称为三次握手。在给定的描述中,我们看到的是一个简单的TCP客户端程序,它尝试连接到指定的IP地址和端口号,但...
**OCP客户端连接OPC服务器**是工业自动化领域中一项重要的技术应用,它涉及到OPC(OLE for Process Control)标准,这是一种数据交换协议,允许不同的自动化设备和软件之间进行通信。在本文中,我们将深入探讨如何...
服务器验证成功后,可能会返回一个JSON对象,包含用户的ID、权限等信息,或者一个简单的状态码(如200表示成功,401表示未授权)。客户端收到响应后,解析JSON数据,根据状态码判断登录是否成功,并更新UI显示。如果...
在Android应用开发中,用户身份验证是至关重要的环节,它涉及到客户端与服务器端的交互,确保用户的安全登录和注册。本示例项目“android登陆注册客户端与服务器端程序”提供了一个完整的解决方案,覆盖了从客户端...
- **TcpClient与TcpListener**:TcpClient用于创建客户端连接,TcpListener则用于服务器监听连接请求。 3. **TCP/IP协议**: - **TCP(Transmission Control Protocol)**:提供面向连接、可靠的字节流服务,确保...
标题中的“聊天程序(客户端与服务器)”指的是一个通信应用程序,它允许用户通过网络进行实时文本、语音或视频交流。在IT领域,这类程序通常涉及到客户端和服务器两种组件,客户端是用户交互的部分,而服务器则是处理...
每个客户端连接都对应一个独立的线程,使得服务器可以并发地处理请求。 - **消息队列**:服务器可能会使用消息队列来缓存和管理来自客户端的消息,确保数据的一致性并避免冲突。 - **安全性**:服务器端需要确保...
- **接受连接**:当有客户端连接请求时,ServerSocket的accept()方法会阻塞,直到有新的连接到来。这个方法会返回一个新的Socket对象,代表与客户端的连接。 - **读写数据**:通过新建立的Socket,服务器可以使用...
在Linux中,套接字API提供了socket()函数用于创建套接字,bind()函数绑定IP地址和端口,listen()函数设置服务器监听连接,accept()函数接收客户端连接,connect()函数是客户端用来连接服务器的。 3. **并发处理**:...
本项目涉及的核心知识点是构建一个完整的登录系统,包括Android客户端、Web服务器以及MySQL数据库。以下将详细阐述每个环节的关键技术和步骤。 首先,**Android客户端**是用户与应用程序交互的界面。在这里,我们...
例如,它可以在工业自动化环境中,让服务器控制多个远程设备,每个设备作为一个客户端连接到服务器,发送状态报告和接收控制指令。 通过这个程序,开发者可以学习到如何在LabVIEW中实现TCP通信,包括设置TCP套接字...
本示例主要讲解如何利用VB Winsock控件来实现客户端连接服务端的登录功能。 首先,了解Winsock控件的基本概念。Winsock是Windows Socket的简称,它是一个API,允许程序员通过TCP/IP协议访问网络。在VB中,Winsock...
这是一种基础的通信验证方式,可以用于测试网络连接是否畅通,或者检查服务器的接收和发送功能是否正常。 `WFMO_Server`可能是一个基于Windows消息机制(Windows Message Object, WMO)实现的服务器端程序。在ACE中...
如果验证成功,服务器将生成一个包含会话ID的JSON响应,返回给客户端。客户端保存会话ID以进行后续的无状态请求。 在项目中,`androidweb`可能是服务器端的代码,包括Struts、Hibernate和Spring的配置文件、Java源...