0

Hello i have made a C server and an android client made in java. , im trying to let the server send the string vibrate and let the phone vibrate for some time. i can see that the client is connected but i dont think the server actualy send any data at all , after i press enter to quit the program for getchar() this error pops up in logcat.

logcat error

01-28 14:10:50.400: W/System.err(30663): java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
01-28 14:10:50.400: W/System.err(30663):    at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552)
01-28 14:10:50.400: W/System.err(30663):    at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
01-28 14:10:50.400: W/System.err(30663):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
01-28 14:10:50.400: W/System.err(30663):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
01-28 14:10:50.400: W/System.err(30663):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
01-28 14:10:50.400: W/System.err(30663):    at java.io.InputStreamReader.read(InputStreamReader.java:244)
01-28 14:10:50.410: W/System.err(30663):    at java.io.BufferedReader.fillBuf(BufferedReader.java:130)
01-28 14:10:50.410: W/System.err(30663):    at java.io.BufferedReader.readLine(BufferedReader.java:390)
01-28 14:10:50.410: W/System.err(30663):    at com.example.rat.RatService$ClientThread.run(RatService.java:76)
01-28 14:10:50.410: W/System.err(30663):    at java.lang.Thread.run(Thread.java:864)
01-28 14:10:50.410: W/System.err(30663): Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
01-28 14:10:50.420: W/System.err(30663):    at libcore.io.Posix.recvfromBytes(Native Method)
01-28 14:10:50.420: W/System.err(30663):    at libcore.io.Posix.recvfrom(Posix.java:131)
01-28 14:10:50.420: W/System.err(30663):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
01-28 14:10:50.420: W/System.err(30663):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
01-28 14:10:50.420: W/System.err(30663):    ... 8 more

C server code.

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

  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(5000);

  // 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");

  //reply to CLIENTCREATESTRUCT
  message = "vibrate";
  send(new_socket, message, strlen(message), 0);
  getchar();
  closesocket(s);
  WSACleanup();
  return 0;
}

ANdroid java client ,

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



    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() {


            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(3000);
                }
                st = null;

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

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

Android Client Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rat"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.Service.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".Service" />
    </application>

</manifest>
alk
  • 69,737
  • 10
  • 105
  • 255

2 Answers2

0

BufferedReader.readLine() blocks until a new-line had been received.

From BufferedReader's documenation:

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

So to fix this issue just also make the server send a new-line by changing this line:

message = "vibrate";

to become:

message = "vibrate\n";

Update:

The error message the client logs clearly shows that the server closes the connection due to ending.

This implies send() had returned. It would be interesting to know which value send() returned.

So I propose you modify this line:

send(new_socket, message, strlen(message), 0);

To become:

{
  int result = send(new_socket, message, strlen(message), 0);

  if (SOCKET_ERROR == result)
  {
    fprintf(stderr, "send() failed with error code: %d\n", WSAGetLastError());
  }
  else
  {
    fprintf(stderr, "Sent %d bytes out of %u.\n", result, strlen(message));
  }
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • @user3244534: Does `readLine()` return? In case yes: What does it return? Be aware that the new-line is returned as part of the string read from the server, so the java code shall test using `st.equals("vibrate\n")` – alk Jan 28 '14 at 13:57
  • Im sorry how you mean readline() return? i just started develop , i changed the java to st.equals("vibrate\n") dosent work still :/ and thats the entire code , except for the mainactivity. – user3244534 Jan 28 '14 at 14:03
  • @user3244534 Run the server code using a debugger to see what really happens, by stepping throuhg the code inspecting the variables values. Do the same for the java code. – alk Jan 28 '14 at 14:12
0

you can try java.util.Scanner for reading jut like java.io.BufferedReader, I mean:

java.util.Scanner sc = new java.util.Scanner(socket.getInputStream(), "US-ASCII").useDelimiter("\\n");
String st = sc.nextLine();
if (st.equals("vibrate")){
    // ...
}

In the server you must add the new line character:

message = "vibrate\n";

Note: If you wish to change separation character from "\n" to any other, just specify on useDelimiter and add it on message at server.

Note: Here is a comparision between Scanner vs BufferedReader.

Community
  • 1
  • 1
Cedmundo
  • 682
  • 4
  • 12
  • i dont realy mind what to use i just wanna know why its not working at this moment bec as far as i know bufferedreader should just work. – user3244534 Jan 28 '14 at 15:33
  • So, try using `new BufferedReader(new InputStreamReader(socket.getInputStream()), "US-ASCII");` and appending "\n" at `message = "vibrate\n"`. – Cedmundo Jan 28 '14 at 15:43
  • The constructor BufferedReader(InputStreamReader, String) is undefined – user3244534 Jan 28 '14 at 16:01
  • Ups, it is inside InputStreamReader(..., "US-ASCII"). http://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html – Cedmundo Jan 28 '14 at 16:18
  • BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); new BufferedReader(new InputStreamReader(socket.getInputStream(),"US-ASCII")); Like this ? btw i can see wireshark is saying a malformed packet is send. – user3244534 Jan 28 '14 at 16:37
  • alright now i suddenly dont get a malformed packet when using port 6000. still not fixed though – user3244534 Jan 28 '14 at 17:05