Android Socket Client循环

时间:2014-02-02 14:16:34

标签: java android sockets client

你好我的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 个答案:

答案 0 :(得分:0)

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

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

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

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

您的服务器将不接受第二次连接尝试,如果它注意到套接字最终关闭(可能根本不会发生),它就会退出。所以你应该解决两件事:

  • 您的服务器应该有一个额外的循环来接受第一个连接后的新连接。您还可以考虑为每个接受的连接创建一个线程,这样它一次只能处理1个以上的客户端。

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

大致在客户端

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
    }
}