Android Socket TCP 服务器与客户端通信

在这里,原理就不讲了,只提供可以运行的代码,以及改如何去在软件上使用它们。

如果实在想要源码:可以点击这边:这里

https://download.csdn.net/download/qq_35594560/10306583

服务器端:

    1.需要Eclipse。(自行安装)

    2.创建两个类(命名为socketserver以及receive,其中socketserver是为了发送信息的,receive为了接收信息,且是一个线程)

    3.socketserver代码如下:

 

import java.io.IOException;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Scanner;

public class socketserver {

    public static void main(String[] args) throws Exception{

        ServerSocket server = new ServerSocket(30003);//在端口9996开一个服务,监听客户端发来的请求,准备接收客户端发来的请求数据

        Socket socket =server.accept();//只有当有客户端请求并连接时,才回返回一个Socket对象,这个对象就是带着客户端请求的那个Socket对象

        System.out.println("server connected!");

        //创建一个PrintWriter的实例对象out来完成服务端向客户端的输出数据的任务,

        PrintWriter out = new PrintWriter(socket.getOutputStream(),true);

        //单独开一个线程接收从客户端过来的请求,在Receive1类中完成数据的接收

        Thread t = new Thread(new Receive1(socket));

        t.start();

        /*一定要理解Socket是一个用于机器之间通信的类*/

        //发送数据给客户端

        Scanner scanner = new Scanner(System.in);//键盘输入服务端要发给客户端的数据

        while(scanner.hasNextLine()){

        String data=scanner.nextLine();

            out.println(data);//将键盘输入的服务端要发给客户端的数据封装在PrintWriter类的对象中

            System.out.println("Server:"+data);

        }

    }

}

4.receive代码:

 

           

import java.io.IOException;

import java.net.Socket;

import java.util.Scanner;

public class Receive1 implements Runnable {

    private Socket socket;

    public Receive1(Socket socket) {

        this.socket=socket;//在服务端接收客户端发来的数据需要调用Receive1()这个方法,就会得到一个Socket对象,这个对象就是携带着客户端请求的socket

    }

    @Override

    public void run() {

        try {

            Scanner scanner=new Scanner(socket.getInputStream());//获得客户端从键盘接收的输入流

            String str = null;

            while(true){

                str=scanner.nextLine();

                System.out.println("Client:"+str);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }//接收数据

    }

}


客户端:

    1.需要android studio。

    2.需要MainActivity以及一个类clintclass

    3.MainActivity代码如下:


package com.example.wuweipeng.exp2;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private EditText etMain;
    private Button btnMain;
    private TextView tvMain;
    private ClientThread mClientThread;

    //在主线程中定义Handler传入子线程用于更新TextView
    private Handler mHandler;

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

        etMain = (EditText) findViewById(R.id.et_main);
        btnMain = (Button) findViewById(R.id.btn_main);
        tvMain = (TextView) findViewById(R.id.tv_main);
        tvMain.setTextColor(Color.WHITE);
        tvMain.setMovementMethod(new ScrollingMovementMethod());
        mHandler=new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 0) {
                    tvMain.append("\n"+"Server:"+ msg.obj.toString());
                }
            }
        };

        //点击button时,获取EditText中string并且调用子线程的Handler发送到服务器
        btnMain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = etMain.getText().toString();
                    tvMain.append("\n"+"Client:"+ msg.obj.toString());
                    mClientThread.revHandler.sendMessage(msg);
                    etMain.setText("");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


        mClientThread = new ClientThread(mHandler);
        new Thread(mClientThread).start();
        tvMain.append("\n"+"已加入群聊");


    }
}

4.ClientThread代码:


package com.example.wuweipeng.exp2;

/**
 * Created by wuweipeng on 2018/3/24.
 */

import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 项目名称:SocketTestTwo
 * 创建人:Double2号
 * 创建时间:2016.11.20 9:16
 * 修改备注:
 */
public class ClientThread implements Runnable {
    private Socket mSocket;
    private BufferedReader mBufferedReader = null;
    private OutputStream mOutputStream = null;
    private Handler mHandler;

    public Handler revHandler;

    public ClientThread(Handler handler) {
        mHandler = handler;
    }

    @Override
    public void run() {
        try {
            mSocket = new Socket("117.25.242.9", 30003);
            Log.d("MainActivity","connect success");
            mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            mOutputStream = mSocket.getOutputStream();

            new Thread(){
                @Override
                public void run() {
                    super.run();
                    try {
                        String content = null;
                        while ((content = mBufferedReader.readLine()) != null) {
                            Log.d("MainActivity",content);
                            Message msg = new Message();
                            msg.what = 0;
                            msg.obj = content;
                            Log.d("MainActivity",msg.toString());
                            mHandler.sendMessage(msg);
                        }
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            }.start();

            //由于子线程中没有默认初始化Looper,要在子线程中创建Handler,需要自己写
            Looper.prepare();

            revHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    if (msg.what == 1) {
                        try {
                            mOutputStream.write((msg.obj.toString() + "\r\n").getBytes("utf-8"));

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





        } catch (IOException e) {
            e.printStackTrace();
            Log.d("MainActivity","");
        }
    }
}

5.XML界面代码:


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

    <TextView
        android:id="@+id/tv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:maxLines = "15"
        android:scrollbars = "vertical"
        android:background="@drawable/img_2"
        />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/tv_main"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_main"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <Button
            android:id="@+id/btn_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="send"/>
    </LinearLayout>


</RelativeLayout>
 

6.最后一步,在AndroidMainfest。xml中添加这句话:

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

以下为试验结果:






 
 

            out.println(data);//将键盘输入的服务端要发给客户端的数据封装在PrintWriter类的对象中

            Sys

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值