Android使用Socket连接阿里云服务器

1.服务端的实现

       1.1.设置IP地址

       IP地址为你的服务器公网IP地址,端口号为已开放的端口号,如果用的是阿里云,需要设置端口号,否则无法进行连接。端口号设置示例如下:

           1.2.服务端的完整代码Server

package socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @author :hly
 * @github :github.com/SiriusHly
 * @blog :blog.csdn.net/Sirius_hly
 * @date :2018/8/19
 */
public class Server implements Runnable {

    public static final String IP = "123.XX.219.XX";
    public static final int PORT = 5000;
    @Override
    public void run() {

        ServerSocket serverSocket = null;
        try {
            //绑定端口
            serverSocket = new ServerSocket(PORT);
            System.out.println("等待连接");
            Socket socket = serverSocket.accept();
            System.out.println("连接成功");
            //获取输入流
            //BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            DataInputStream in = new DataInputStream(socket.getInputStream());
            //获取输出流
            //BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            //读取信息
            System.out.println("读取1");
            String str = in.readUTF();
            System.out.println("读取2");
            System.out.println("服务器接收到的消息为:"+str);
            //发送信息给客户端
            out.writeUTF("1");
            out.flush();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
                if (serverSocket!=null){
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }
    }
    public static void main(String[] args) {
        Thread myThread = new Thread(new Server());
        myThread.start();
    }
}

1.3.readLine注意事项

    如果传输单条数据,输入流可能无法使得可以接收到数据,代码如下:

 //BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = in.readLine() 

     上面的代码接收不到数据,因为in.readLine是一个阻塞方法,只要没有断开连接,就会一直进行等待,而不是返回null,当断开连接后,就会出现异常,通常需要用一定的分隔符,socket适用麻烦,下面是其源码:

String readLine(boolean ignoreLF) throws IOException {  
    StringBuffer s = null;  
    int startChar;  
        synchronized (lock) {  
            ensureOpen();  
        boolean omitLF = ignoreLF || skipLF;  
        bufferLoop:  
        for (;;) {  
        if (nextChar >= nChars)  
            fill(); //在此读数据  
        if (nextChar >= nChars) { /* EOF */  
            if (s != null && s.length() > 0)  
            return s.toString();  
            else  
            return null;  
        }  
      ......//其它  
}  
  
private void fill() throws IOException {  
    ..../其它  
    int n;  
    do {  
        n = in.read(cb, dst, cb.length - dst); //实质  
    } while (n == 0);  
    if (n > 0) {  
        nChars = dst + n;  
        nextChar = dst;  
    }  
    }  

2.客户端的实现

    2.1.添加许可证

     客户端为安卓客户端,在进行网络连接时,需要在配置文件AndroidManifest.xml里面加上对网络访问的允许,代码如下:

<uses-permission android:name="android.permission.INTERNET" />

   2.2.前端界面代码

    这里是显示部分的代码,完整代码就不给出了,可以在笔者的github里面下载:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:layout_marginTop="230dp"
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:orientation="vertical"
        android:layout_centerInParent="true">

        <EditText
            android:id="@+id/userId"
            android:hint="账号"
            android:padding="10dp"
            android:layout_margin="10dp"
            android:layout_width="250dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:textColorHint="@color/silver"

            />
        <EditText
            android:id="@+id/userPassword"
            android:hint="密码"
            android:padding="10dp"
            android:layout_margin="10dp"
            android:layout_width="250dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:textColorHint="@color/silver"

            />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent">
            <Button
                android:text="登录"
                android:id="@+id/btnLogin"
                android:layout_margin="30dp"
                android:layout_width="100dp"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:background="@color/colorAccent"/>
            <Button
                android:id="@+id/btnRegister"
                android:text="注册"
                android:layout_margin="30dp"
                android:layout_width="100dp"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:background="@color/colorPrimary"/>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

  页面截图:

   2.3.后台代码

    对一些事件进行监听

package com.example.hly.app.activity;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.hly.app.R;
import com.example.hly.app.thread.LoginThread;

public class MainActivity extends AppCompatActivity {

    private Button btnLogin;
    private EditText txtUserId;
    private EditText txtUserPassword;
    private ProgressBar progressBar;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnLogin = (Button)findViewById(R.id.btnLogin);
        txtUserId = (EditText)findViewById(R.id.userId);
        txtUserPassword =(EditText)findViewById(R.id.userPassword);
        progressBar = (ProgressBar)findViewById(R.id.progressBar);
        //progressBar.setVisibility(View.GONE);

        //登录事件监听
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //progressBar.setVisibility(View.VISIBLE);

                try {
                    LoginThread loginThread = new LoginThread(txtUserId.getText().toString(),txtUserPassword.getText().toString());
                    Thread t = new Thread(loginThread);
                    t.start();
                    t.join();
                    //progressBar.setVisibility(View.GONE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if(LoginThread.message.equals("1")) {
                    Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT);
                    Intent intent = new Intent();
                    intent.setClass(MainActivity.this, Index.class);
                    MainActivity.this.startActivityForResult(intent, 1);
                }else{
                    Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT);
                }

            }
        });

    }

}

   2.4.Client端Socket

package com.example.hly.app.thread;

import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * Created by hly on 2018/8/19.
 */

public class LoginThread implements Runnable {
    private String userId ;
    private String userPassword ;
    public static String message =" ";

    public static final  String IP = "123.xx.xx.xx";
    public static final  int PORT = 5000;

    public LoginThread() {
    }
    public LoginThread(String userId, String userPassword) {
        this.userId = userId;
        this.userPassword = userPassword;
    }
    @Override
    public void run() {

        try {
            Log.e("开始连接","Start");
            Socket socket = new Socket(IP,PORT);
            Log.e("成功连接","success");
            //获取输入流
            //BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            DataInputStream in = new DataInputStream(socket.getInputStream());
            //获取输出流
            //BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.writeUTF(userId+" "+userPassword);
            //刷新发送
            out.flush();
            message = in.readUTF();
            System.out.print("接收的数据为:"+in.readUTF());
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

   3.部署服务器

     3.1.打包jar

            1.首先为了方便部署,需要把服务端代码打包成jar包,在IDEA上是这样打包的:

      file->preject Constructure,接着,步骤如下图:

   

        2.接着会出现以下选项,选择extract to the target JAR打包的是一个jar包,第二个是带上你项目的所有jar包,一般选择第一个,选择第二个可能会出现无法加载主类。详情:https://www.cnblogs.com/acm-bingzi/p/6593892.html

   

    3.在这里,可以选择需要添加的JAR包,不需要可以不用填,完成后点击ok

 

   4.然后我们在IDEA上方找到build,进行以下操作进行了

   5.之后可以在这个路径下找到jar包

  4.运行技巧

    4.1.cmd运行

   得到jar包之后,双击如果不能运行和连接,一般来说可以连接可以使用命令执行,如下:java -jar +你的jar包,之后程序运行。

  如果不能双加运行,打开注册表

依次知道到HKEY_CLASS_ROOT->Applications->javaw.exe修改默认值即可

 4.2.bat文件运行

        如果你行通过直接点击来运行而不需要每一次都很麻烦输入命令,教你一个技巧,新建文本文档,修改后缀名为bat

然后加入以下格式.

D: 
cd WEBPRODUCTION\App\out\artifacts\App_jar
java -jar App.jar
pause

D: //代表去D盘

cd //代表进入目录

接下来执行jar

pause让cmd停止

运行效果图:

猜你喜欢

转载自blog.csdn.net/Sirius_hly/article/details/81844946