Android socket AsyncTask和linux服务端通讯

3 篇文章 0 订阅
3 篇文章 0 订阅

android 3以后,在UI主线程里面不能访问网络,因为访问网络可能导致程序崩溃,UI界面无法刷新,所以只有通过线程来完成,但对于线程许多人不是很清晰,而且代码会 很多,但是现在android提供了AsyncTask来处理异步任务。

客户端代码:

package com.test;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

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.net.UnknownHostException;

public class MainActivity extends Activity implements View.OnClickListener {


        private TextView TextTime;

        private Button buttonTime;


        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                TextTime        =(TextView)this.findViewById(R.id.textViewTime);

                buttonTime      = (Button)this.findViewById(R.id.button2);

                buttonTime.setOnClickListener(this);
        }



        @Override
        public void onClick(View view) {
                switch (view.getId())
                {
                        case R.id.button2:
                        //注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常
                                MyTask    mTask = new MyTask();
                                mTask.execute("119.29.85.118");
                                break;
                        default:
                                break;
                }
        }

        private class MyTask extends AsyncTask<String,Integer,String>{

                //onPreExecute方法用于在执行后台任务前做一些UI操作
                @Override
                protected void onPreExecute() {
                        TextTime.setText("fwe");
                }

                //doInBackground方法内部执行后台任务,不可在此方法内修改UI
                protected String doInBackground(String... parms) {

                        Socket socket =null;

                        try {
                                socket = new Socket(parms[0], 8888);
                                System.out.println("socket has connected");

                                //2.得到socket读写流

                                OutputStream os=socket.getOutputStream();
                                OutputStreamWriter pw=new OutputStreamWriter (os);

                                BufferedWriter bw = new BufferedWriter(pw);

                                bw.write("TIME");
                                bw.flush();
                                // 从服务端程序接收数据
                                InputStream ips = socket.getInputStream();
                                InputStreamReader ipsr = new InputStreamReader(ips);
                                BufferedReader br = new BufferedReader(ipsr);
                                String s = "";
                                String result="";
                                while((s = br.readLine()) != null) {
                                        result += s;
                                        System.out.println(s);
                                }
                                socket.close();
                                return result;
                        } catch (UnknownHostException e) {
                                e.printStackTrace();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }

                        return "fweffwef";
                }
                //onProgressUpdate方法用于更新进度信息
                protected void onProgressUpdate(Integer... progress) {
                      //  progressBar.setProgress(progresses[0]);
                }
                //onPostExecute方法用于在执行完后台任务后更新UI,显示结果
                protected void onPostExecute(String result) {
                        TextTime.setText(result);
                }

                //onCancelled方法用于在取消执行中的任务时更改UI
                @Override
                protected void onCancelled() {
                }
        }
}

添加网络访问权限:

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

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.test.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ButtonPost"
        android:id="@+id/buttonpost"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button2"
        android:layout_below="@+id/buttonpost"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="55dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button3"
        android:layout_centerVertical="true"
        android:layout_alignLeft="@+id/button2"
        android:layout_alignStart="@+id/button2"/>

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="70dp"
        android:text="Medium Text"
        android:id="@+id/textViewTime"
        android:layout_below="@+id/button3"
        android:layout_marginTop="68dp"/>
</RelativeLayout>

linux服务代码还是和上篇文章一样,所以说一般服务端开发代码都变化比较少:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 3
static void handle_connect(int s_s)
{   
    int s_c;                                    /*客户端套接字文件描述符*/
    struct sockaddr_in from;                    /*客户端地址*/
    socklen_t len = sizeof(from);

    /*主处理过程*/
    while(1)
    {
        /*接收客户端连接*/
        s_c = accept(s_s, (struct sockaddr*)&from, &len);
        time_t now;                             /*时间*/
        char buff[BUFFLEN];                     /*收发数据缓冲区*/
        int n = 0;
        memset(buff, 0, BUFFLEN);               /*清零*/
        n = recv(s_c, buff, BUFFLEN,0);     /*接收发送方数据*/
        if(n > 0 && !strncmp(buff, "TIME", 4))  /*判断是否合法接收数据*/
        {
            memset(buff, 0, BUFFLEN);           /*清零*/
            now = time(NULL);                   /*当前时间*/
            sprintf(buff, "%24s\r\n",ctime(&now));  /*将时间复制入缓冲区*/
            send(s_c, buff, strlen(buff),0);    /*发送数据*/
        }       
        /*关闭客户端*/
        close(s_c); 
    }

}
void sig_int(int num)
{
    exit(1);    
}
int main(int argc, char *argv[])
{
    int s_s;                                    /*服务器套接字文件描述符*/
    struct sockaddr_in local;                   /*本地地址*/    
    signal(SIGINT,sig_int);

    /*建立TCP套接字*/
    s_s = socket(AF_INET, SOCK_STREAM, 0);

    /*初始化地址和端口*/
    memset(&local, 0, sizeof(local));           /*清零*/
    local.sin_family = AF_INET;                 /*AF_INET协议族*/
    local.sin_addr.s_addr = htonl(INADDR_ANY);  /*任意本地地址*/
    local.sin_port = htons(SERVER_PORT);        /*服务器端口*/

    /*将套接字文件描述符绑定到本地地址和端口*/
    bind(s_s, (struct sockaddr*)&local, sizeof(local));
    listen(s_s, BACKLOG);                   /*侦听*/

    /*处理客户端连接*/
    pid_t pid[PIDNUMB];
    int i =0;
    for(i=0;i<PIDNUMB;i++)
    {
        pid[i] = fork();
        if(pid[i] == 0)                         /*子进程*/
        {
            handle_connect(s_s);
        }
    }
    while(1);

    close(s_s);

    return 0;
}

程序实现的效果是,点击第二个按钮,在TextView上面显示从服务端获得的值。在本例中,也就是时间。

技术在不断的积累中慢慢变强。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值