android Linux 网络连接

来源:互联网 发布:linux系统编程手册pdf 编辑:程序博客网 时间:2024/05/17 22:28

 最近由于工作需要,需要在建立android app和Linux app 之间建立多对一网络连接,网络是wifi p2p 的。

android app 作为网络的服务器端,它主要包含两个模块,

1、ReceiveServer ,它主要创建服务器端和管理客户端连接

2、SourceListener,它主要对客户端的抽象,代表一个客户端连接

Linux app 作为网络连接的客户端,他只有一个模块

SenderService ,它主要连接到网络,并收发数据

       

一、在android app 端建立网络服务器以及多个客户端的管理

ReceiveServer 是服务器管理模块,监听客户端连接private class ReceiveServer implements Runnable {private static final int RECEIVE_SERVER_DEFAULT_PORT = 7238; //端口号private static final int RECEIVE_SERVER_MAX_CONNECTIONGS = 16; //最多连接数private ServerSocket mServer; //建立android 服务器用private Thread mThread; //server 活动处理线程private ExecutorService mThreadPool; //客户端线程集合private ReceiveServer(){}private boolean start() {if(mThread != null){return false;}try{mServer = new ServerSocket(RECEIVE_SERVER_DEFAULT_PORT);}catch (IOException ex) {Log.w(TAG, "Failure to open receive Server" + ex);return false;}mThread = new Thread(this,TAG);mThreadPool = Executors.newFixedThreadPool(RECEIVE_SERVER_MAX_CONNECTIONGS);mThread.start();return true;}private boolean stop(){if(mThread != null){mThread.interrupt();if(mThreadPool != null){try{mThreadPool.shutdownNow();}catch (SecurityException e) {Log.w(TAG, "Could not stop all threads");}} mThread = null;mThreadPool = null;try {mServer.close();mServer = null;return true;} catch (IOException e) {Log.w(TAG, "Could not close the server");}}return false;}public void run(){if (DBG) Log.d(TAG,"Thread running");try{if(DBG) Log.d(TAG,"mServer is " + mServer.toString() + "local address is " + InetAddress.getLocalHost().getHostAddress());}catch (IOException ex) {Log.w(TAG, "Failure to open receive Server" + ex);}while(Thread.currentThread() == mThread){if(DBG) Log.d(TAG, "Thread.currentThread() == mThread");try{Socket client = mServer.accept(); //收到client响应if(mThreadPool != null){mThreadPool.submit(new SourceListener(client)); //启动该客户端处理的线程,并将该线程加入到mThreadPool中}else {try {client.close();} catch (IOException e) {e.printStackTrace();}}}catch (Exception e) {Log.w(TAG, "mServer.accept error: ", e);}}}}

SourceListener是客户端管理模块private class SourceListener implements Runnable{private Socket mClient;private String mMac;private OutputStream mOut;private InputStream mIn;SourceListener(Socket client){mClient = client;try{mIn = mClient.getInputStream();mOut = mClient.getOutputStream();}catch(IOException e){e.printStackTrace();}}public void run(){if(DBG) Log.d(TAG,"SourceListener run");try{byte data[] = CMD_READY.getBytes();mOut.write(data);if(DBG) Log.d(TAG,"send Ready to client");byte[] buf = new byte[64];int len;len = mIn.read(buf);if(DBG) Log.d(TAG, "len is " + len + buf);final String request = new String(buf);//mDataIn.readLine();String command;String mac;String ip;if(DBG) Log.d(TAG, "Read from source is " + request);String parms[] = request.split(" ");if(parms.length != 4)return;command = parms[0];mac = parms[1];ip = parms[2];if(command.equals(START_PLAY_CMD)){sendPlayWfdBroadcast(mac,ip);}}catch(IOException e) {Log.w(TAG, "read Line error " + e);}finally {if(DBG) Log.d(TAG, "Do nothing");}}}



二、在Linux app 中建立客户端。

#include "SenderService.h"#define RECEIVE_SERVER_DEFAULT_PORT 7238 //端口#define START_PLAY_CMD "START_WFD"#define SERVER_IP_ADDR"192.168.49.1"namespace android {SenderService::SenderService(const char* mac){mSockets = -1;mSendAgain = false;memset(mMac, 0, sizeof(mMac));if(mac != NULL){memcpy(mMac,mac, strlen(mac));}}SenderService::~SenderService(){}status_t SenderService::createClient(const char * sourceHost){status_t err = OK;int32_t sourcePort = RECEIVE_SERVER_DEFAULT_PORT;if(sourceHost == NULL)return -1;memset(mIP, 0, sizeof(mIP));memcpy(mIP,sourceHost,sizeof(mIP));mSockets = socket(AF_INET,SOCK_STREAM, 0);if (mSockets < 0){err = -errno;return err;}struct sockaddr_in addr;memset(addr.sin_zero, 0, sizeof(addr.sin_zero));addr.sin_family = AF_INET;struct hostent *ent= gethostbyname(SERVER_IP_ADDR);    if (ent == NULL) {        err = -h_errno;close(mSockets);return err;    }addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;    addr.sin_port = htons(sourcePort);in_addr_t x = ntohl(addr.sin_addr.s_addr);    ALOGD("connecting to %d.%d.%d.%d:%d",          (x >> 24),          (x >> 16) & 0xff,          (x >> 8) & 0xff,          x & 0xff,          ntohs(addr.sin_port));//连接服务器    int res = connect(mSockets, (const struct sockaddr *)&addr, sizeof(addr));if(res < 0)return res;ALOGD("connected ");return err;}//像服务器发送数据int SenderService::writeData(){int size;memset(mSenderBuf, 0, sizeof(mSenderBuf));sprintf(mSenderBuf,"%s %s %s end",START_PLAY_CMD,mMac,mIP);ALOGD("SEND to Recever %s",mSenderBuf);do{size = send(mSockets, mSenderBuf, sizeof(mSenderBuf),0);ALOGD("Send size is %d",size);}while(size < 0 && errno == EINTR);if(size < 0){ALOGE("Send failed");}return size;}//从服务器端读取数据status_t SenderService::readData(){ssize_t size;memset(mReceiveBuf,0, sizeof(mReceiveBuf));struct sockaddr_in remoteAddr;socklen_t remoteAddrLen = sizeof(remoteAddr);do{size = recvfrom(mSockets, mReceiveBuf, sizeof(mReceiveBuf),0,(struct sockaddr *)&remoteAddr, &remoteAddrLen);}while(size < 0 && errno == EINTR);uint32_t connect_ip = ntohl(remoteAddr.sin_addr.s_addr);ALOGD("Receive from %u.%u.%u.%u is %s" ,                            connect_ip >> 24,                            (connect_ip >> 16) & 0xff,                            (connect_ip >> 8) & 0xff,                            connect_ip & 0xff,mReceiveBuf);return OK;}//分析从服务器端读取数据int SenderService::parseData(){if(strstr(mReceiveBuf, "Ready")){sp<AMessage> msg = new AMessage(kWhatSendData, id());msg->post();}else if(strstr(mReceiveBuf, "Echo")){mSendAgain = false;}return 0;}void SenderService::start(){sp<AMessage> msg = new AMessage(kWhatReadData, id());msg->post();}//void SenderService::onMessageReceived(        const sp<AMessage> &msg) {    status_t ret;ALOGD(" [%s %d] msg->what:%d", __FUNCTION__,__LINE__,msg->what());switch(msg->what()){case kWhatReadData:ret = readData();if(ret == OK){parseData();}break;case kWhatSendData:{writeData();}break;default:ALOGE("Unknow cmd %d",msg->what());break;}}



0 0
原创粉丝点击