Socket通信:Linux服务器与多个Android客户端

Socket通信:Linux服务器与多个Android客户端

1. Linux Server:

#include 
//head files of Linux
#include
#include   //for fork and read
#include   //for socket
#include  //for socket
#include // for bzero
#include
#include 
#include 


using namespace std;

struct data {
    int server_fd;
    unsigned int sin_size;
};

void *acceptClient(void *param) {
    data *data1 = (data *) param;
    int client_fd;
    int sock = data1->server_fd;
    unsigned int sin_size = data1->sin_size;
    sockaddr_in remoteAddr;
    const int MAXSIZE = 1024;

    if ((client_fd = accept(sock, (sockaddr *) (&remoteAddr), &sin_size)) == -1) {
        cerr << "accept error!" << endl;

    }
    cout << " 已和用户建立链接 " << static_cast<char *>(inet_ntoa(remoteAddr.sin_addr)) << endl;

    // ---------------- 逻辑部分 -------------------//
    int count = -1;
    while (count<5) {
        count++;
        if (1) {
            //----接受消息
            cout<<"\n 等待接受消息..."<int rval;
            char buf[MAXSIZE];
            if ((rval = read(client_fd, buf, MAXSIZE)) < 0) {
                cout << "Reading stream error!\n";
                continue;
            }
            cout << "用户发送的信息为:" << buf << endl;

            //-----发送消息
            const char *msg = "67.8元";
            if (send(client_fd, const_cast<char *>(msg), strlen(msg), 0) == -1)
                cerr << "send error!" << endl;
            }
        }
    }
    close(client_fd);
//    exit(0);
}

void server()
{
    // 参数设置
    const unsigned short SERVERPORT = 53553;
    const int BACKLOG = 10; //10 个最大的连接数
    const int MAXSIZE = 1024;
    int sock, client_fd;
    sockaddr_in myAddr;
    sockaddr_in remoteAddr;
    sock = socket(AF_INET, SOCK_STREAM, 0);

    //create socket
    if( sock == -1)
    {
        cerr<<"socket create fail!"<exit(1);
    }

    cout<<"sock :"<// bind
    myAddr.sin_family = AF_INET;
    myAddr.sin_port = htons(SERVERPORT);
    myAddr.sin_addr.s_addr = INADDR_ANY;
    bzero( &(myAddr.sin_zero), 8);
    if(bind(sock, (sockaddr*)(&myAddr), sizeof(sockaddr)) ==-1 )
    {
        cerr<<"bind error!"<exit(1);
    }

    // 服务器ip和端口
    cout << " server ip: " << inet_ntoa(myAddr.sin_addr) << endl;
    cout << " server port: " << SERVERPORT <//myAddr.sin_port

    //listen
    if(listen(sock, BACKLOG) == -1)
    {
        cerr<<"listen error"<exit(1);
    }

    // 创建多个线程连接用户端
    pthread_t tids[BACKLOG];
    int threadID = 0;
    while(threadID<10) {
        unsigned int sin_size = sizeof(sockaddr_in);
        data threadParam;
        threadParam.server_fd = sock;
        threadParam.sin_size = sin_size;
        int ret = pthread_create(&tids[threadID],NULL,acceptClient,(void *)&threadParam);
        threadID++;
        if (ret != 0)
        {
            cout << "pthread_create error: error_code=" << ret << endl;
        }
}

2. Android 客户端


import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {

    private TextView editText_1;
    private EditText editText_ip,editText_data;
    private OutputStream outputStream = null;
    private Socket socket = null;
    private String ip;
    private String data;
    private boolean socketStatus = false;
    StringBuffer stringBuffer = new StringBuffer();

    private String textToShow = "待支付金额:";

    public Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case 1:
                    textToShow+="\n";
                    textToShow+=msg.obj.toString();
                    editText_1.setText(textToShow);
                    break;
                case 2:
                    editText_1.setText(msg.obj.toString());
                    stringBuffer.setLength(0);
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        editText_ip = (EditText) findViewById(R.id.et_ip);
        editText_data = (EditText) findViewById(R.id.et_data);
        editText_1 = (TextView) findViewById(R.id.text1);

    }


    public void connect(View view){
        ip = editText_ip.getText().toString();
        if(ip == null){
            Toast.makeText(MainActivity.this,"please input Server IP",Toast.LENGTH_SHORT).show();
        }

        Thread thread = new Thread(){
            @Override
            public void run() {
                super.run();

                if (!socketStatus) {
                    try {
                        // ip 和端口要和服务器一致
                        socket = new Socket(ip,53553);
                        if(socket == null){
                        }else {
                            socketStatus = true;
                        }
                        outputStream = socket.getOutputStream();
                    } catch (IOException e) {
                        Toast.makeText(MainActivity.this,"socket connect failed",Toast.LENGTH_SHORT).show();
                        e.printStackTrace();
                    }
                }

            }
        };
        thread.start();
    }


    public void send(View view){
        // 发送数据
        data = editText_data.getText().toString();
        if(data == null){
            Toast.makeText(MainActivity.this,"please input Sending Data",Toast.LENGTH_SHORT).show();
        }else {
            //在后面加上 '\0' ,是为了在服务端方便我们去解析;
            data = data + '\0';
        }

        Thread thread = new Thread(){
            @Override
            public void run() {
                super.run();
                if(socketStatus){
                    try {
                        outputStream.write(data.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                //接受返回数据
                int len;
                byte[] bytes = new byte[20];
                InputStream inputStream;
                StringBuffer stringBuffer = new StringBuffer();

                try{
                    inputStream = socket.getInputStream();
                    while ((len = inputStream.read(bytes)) != -1) {
                        for(int i=0; ichar)bytes[i]);
                        }
                        Message message = handler.obtainMessage();
                        message.what = 1;
                        message.obj = stringBuffer;
                        handler.sendMessage(message);
                        break;
                    }

                } catch (Exception e){ }
            }
        };
        thread.start();
    }

    /*当客户端界面返回时,关闭相应的socket资源*/
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        /*关闭相应的资源*/
        try {
            outputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
  • 服务器端ip说明:ip = 0.0.0.0 可以本机和本机的端口间任意通信,在局域网中,要使用192.168.xxx.xxx的ip,保证客户端和服务器端口ip一致

最后,完整demo,以及Linux的客户端,Andoird的服务器端的下载链接:

http://download.csdn.net/download/burning_keyboard/10229385

你可能感兴趣的:(编程笔记)