简体   繁体   English

Android Socket客户端循环

[英]Android Socket Client loop

Hello i have a problem with my android client loop , i tested the server with wireshark and i can see it sends the string just fine , when i debug the client i can see it runs good once but when it loops again and it retrieves the second string it looks like the Bufferedinput is empty and it never contione thought the .readline() 您好,我的android客户端循环有问题,我用Wireshark测试了服务器,我可以看到它很好地发送了字符串,当我调试客户端时,我可以看到它一次运行良好,但是当它再次循环并检索到第二个字符串时字符串,它看起来像Bufferedinput为空,并且从未认为.readline()

Android client : 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 server code incase needed: 需要的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;
}

Your client creates new connections that read just 1 line (and then doesn't clean up / close the socket) 您的客户端创建仅读取1行的新连接(然后不清理/关闭套接字)

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

Your server on the other hand accepts 1 connection, reads within a loop from that connection and quits. 另一方面,您的服务器接受1个连接,从该连接中循环读取并退出。

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

Your server will not accept the second connection attempt and if it notices that the socket is eventually closed (which may not happen at all) it would just quit. 您的服务器将不会接受第二次连接尝试,并且如果它注意到套接字最终被关闭(这可能根本不会发生),它将退出。 So you should fix 2 things: 因此,您应该修复2件事:

  • Your server should have an additional loop to accept new connections once the first is closed. 一旦第一个服务器关闭,您的服务器应该有一个附加循环来接受新连接。 You could also consider creating a thread per accepted connection so it can handle more than just 1 client at a time. 您还可以考虑为每个接受的连接创建一个线程,这样它一次可以处理多个客户端。

  • Your client should not open a new connection within the loop. 您的客户端不应在循环内打开新连接。 You could add a loop to re-connect in case the connection drops though. 如果连接断开,您可以添加一个回路以重新连接。 And you must make sure that you close the connection properly so your server will eventually return from the loop. 并且必须确保正确关闭连接,以便服务器最终从循环中返回。

Roughly this on client side 大概在客户端

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