有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Androidsocket客户端循环

您好,我的安卓客户端循环有问题,我用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 安卓.R.string;
import 安卓.app.Service;
import 安卓.content.Context;
import 安卓.content.Intent;
import 安卓.hardware.Camera;
import 安卓.hardware.Camera.Parameters;
import 安卓.os.IBinder;
import 安卓.os.Vibrator;
import 安卓.util.Log;
import 安卓.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) 个答案

  1. # 1 楼答案

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

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

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

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

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

    • 一旦第一个连接关闭,服务器应该有一个额外的循环来接受新的连接。您还可以考虑在每个接受的连接上创建一个线程,这样它就可以一次处理多于1个客户端。p>

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

    在客户端大致上就是这样

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