繁体   English   中英

Android Socket客户端循环

[英]Android Socket Client loop

您好,我的android客户端循环有问题,我用Wireshark测试了服务器,我可以看到它很好地发送了字符串,当我调试客户端时,我可以看到它一次运行良好,但是当它再次循环并检索到第二个字符串时字符串,它看起来像Bufferedinput为空,并且从未认为.readline()

Android客户端:

 package com.example.leopard;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;

import android.R.string;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;

public class leopardService extends Service{
    private boolean isRunning = false;
    private static final  String SERVER_IP = "192.168.178.11";
    private static final int SERVERPORT = 6000;
    private Socket socket;
    Thread ClientThread = null;
    String st = null;
    private Camera camera;


    public void onCreate() {

    }


    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);

        // Annoucment about starting serivce

        // Start a Thread Called MyThread
        isRunning = true;
        this.ClientThread = new Thread(new ClientThread());
        this.ClientThread.start();

        // Keep running until it explicitly stopped.
        // stopped so returns sicky
        return START_STICKY;
    }
    // code


    public void onDestroy(){
        super.onDestroy();
        // stop background Thread
        isRunning = false;


    }

    public class ClientThread implements Runnable {
        public void run() {
            isRunning = true;

            {
                while( isRunning = true){
            try{
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                socket = new Socket(serverAddr,SERVERPORT);


                BufferedReader input =  new BufferedReader(new InputStreamReader(socket.getInputStream()));


                String st = input.readLine();

                if (st.equals("vibrate")){
                    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                    v.vibrate(1000);
                }
                else if(st.equals("quit")){
                    Vibrator b = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                            b.vibrate(3000);

                isRunning = false;
                }









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




    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}

需要的C服务器代码:

#include <winsock2.h>
#include <stdio.h>

#define BUF_LEN 100

int main(int argc, char *argv[])
{
    WSADATA wsa;
    SOCKET s , new_socket;
    struct sockaddr_in server , client;
    int c;
    int result;
    char message[BUF_LEN];
    bool IsRunning;
    IsRunning = true;

if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
    printf("ERROR initlizaing winsock2 dll : %d",WSAGetLastError());
    return 1; // exit program with error.
}

printf("INitialised.\n");

// create a socket
 s = socket(AF_INET,SOCK_STREAM, 0);
if(s == INVALID_SOCKET)
{
    printf("error at creating socket :%d" ,WSAGetLastError());
    WSACleanup();
    return 1;
}

printf("socket created");

//Sockad_addr in strucsture prepare
memset(&server, 0, sizeof server);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(6000);

// bind the socket

if (bind(s , (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
    printf("Bind fialed with errror code : %d",WSAGetLastError());
    closesocket(s);
    WSACleanup();
    return 1;
}


listen(s , 3);

printf("waiting for incoming connections");
// this part is what i dont understand.
c = sizeof(struct sockaddr_in);
new_socket = accept(s , (struct sockaddr *)&client,&c);
if(new_socket == INVALID_SOCKET)
{
    printf("accept fialed with error code : %d" ,WSAGetLastError());

    closesocket(s);
    WSACleanup();
    return 1;
}

printf("Connection acceptëd");
//message ="quit\n";
//reply to CLIENTCREATESTRUCT
while(IsRunning == true){
scanf("%s",message);
if(message == "stop_thread"){
    IsRunning = false;
}

strcat(message, "\n");
    result = send(new_socket , message , strlen(message) , 0);
    if(result == SOCKET_ERROR)
    {
        printf("send failed with error codfe %d\n",WSAGetLastError());

    }
    else{
        printf("sent %d bytes out of %u \n",result,strlen(message));
    }
memset(message, 0 ,100);
}
getchar();
closesocket(s);
WSACleanup();
return 0;
}

您的客户端创建仅读取1行的新连接(然后不清理/关闭套接字)

while( isRunning = true){
                socket = new Socket(serverAddr,SERVERPORT);
                string = readLine();
}

另一方面,您的服务器接受1个连接,从该连接中循环读取并退出。

while(IsRunning == true){
    scanf("%s",message);
}
return 0;

您的服务器将不会接受第二次连接尝试,并且如果它注意到套接字最终被关闭(这可能根本不会发生),它将退出。 因此,您应该修复2件事:

  • 一旦第一个服务器关闭,您的服务器应该有一个附加循环来接受新连接。 您还可以考虑为每个接受的连接创建一个线程,这样它一次可以处理多个客户端。

  • 您的客户端不应在循环内打开新连接。 如果连接断开,您可以添加一个回路以重新连接。 并且必须确保正确关闭连接,以便服务器最终从循环中返回。

大概在客户端

try{
    InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
    socket = new Socket(serverAddr,SERVERPORT);
    while( isRunning = true){
        .. readline
    }
} finally {
    if (socket != null) {
        // send "stop_thread", close OutputStream
        // close socket
    }
}        

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM