【问题标题】:android client not getting response from C server socketandroid客户端没有从C服务器套接字得到响应
【发布时间】:2016-03-30 07:46:29
【问题描述】:

我能够将字符串从 android 客户端发送到 C 服务器。 但我无法将响应从服务器返回到 android 客户端。 android 客户端没有获取数据。我想“敬酒”从 c 服务器得到的响应。

服务器代码(c):

#include <stdio.h>
#include <stdlib.h>

#include <netdb.h>
#include <netinet/in.h>

#include <string.h>

int main( int argc, char *argv[] ) {
int sockfd, newsockfd, portno, clilen;
char buffer[256];
char g[255];
char *message;
struct sockaddr_in serv_addr, cli_addr;
int  n;
int p;

/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0) {
  perror("ERROR opening socket");
  exit(1);
}

/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5011;

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("192.168.1.125");
//serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);

/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
  perror("ERROR on binding");
  exit(1);
}

/* Now start listening for the clients, here process will
  * go in sleep mode and will wait for the incoming connection
*/

listen(sockfd,5);
clilen = sizeof(cli_addr);

/* Accept actual connection from the client */
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);

if (newsockfd < 0) {
  perror("ERROR on accept");
  exit(1);
}

/* If connection is established then start communicating */
bzero(buffer,256);
n = read( newsockfd,buffer,255 );

if (n < 0) {
  perror("ERROR reading from socket");
  exit(1);
}

printf("Here is the message: %s\n",buffer);

/* Write a response to the client */

//int man = 12345;
message ="hello\n";

n = write(newsockfd, message,strlen(message));


return 0;
}

****Android 客户端:****

import android.app.Activity;
import android.graphics.Color;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Formatter;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;


public class ScreenTwo extends Activity {
    EditText et;
String txt,ssid,key;
WifiManager wifiManager;
private Socket socket;

private Socket clientSocket;
private BufferedReader input;


static final int SERVERPORT = 5047;
private static final String SERVER_IP = "192.168.1.125";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.screen2);
    new Thread(new ClientThread()).start();


}


 public void onClick(View v) {

    try {
         EdritText et = (EditText) findViewById(R.id.tb1);
         Sting str = et.getText().toString();
         PrintWriter out = new PrintWriter(new BufferedWriter(
                 new OutputStreamWriter(socket.getOutputStream())),
                 true);
         out.println(str + "\n");
         out.flush();


         BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         String read = input.readLine();
         Toast.makeText(this, read, Toast.LENGTH_LONG).show();

        //ready to receive data from server
         //BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         //System.out.println(in.readLine());
         //Toast.makeText(this, in.readLine(), Toast.LENGTH_LONG).show();
     } catch (UnknownHostException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

public void onEnterBtn(View v)
{
    //Toast.makeText(this, "Clicked on Button", Toast.LENGTH_LONG).show();
    et=(EditText)findViewById(R.id.tb1);
    txt=et.getText().toString();
    Toast.makeText(this, txt, Toast.LENGTH_LONG).show();

    Button disp = (Button)findViewById(R.id.dispbtn);
    disp.setBackgroundColor(Color.parseColor(txt));



} 

public void onbuttonwifi(View v)
{
    //Toast.makeText(this, "Clicked on Button", Toast.LENGTH_LONG).show();
    WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
    WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
    int ip = wifiInfo.getIpAddress();
    String ipAddress = Formatter.formatIpAddress(ip);
    Toast.makeText(this, ipAddress, Toast.LENGTH_LONG).show();

 }

class ClientThread implements Runnable {
    @Override
    public void run() {
         try {
             InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
             socket = new Socket(serverAddr, SERVERPORT);

         } catch (UnknownHostException e1) {
             e1.printStackTrace();
         } catch (IOException e1) {
             e1.printStackTrace();
         }
    }
}

}

提前致谢:)

【问题讨论】:

  • 您的问题中有错字,不清楚哪些有效,哪些无效。这不应该在任何一个方向上工作,因为你在 android 的主线程上联网。
  • 所以我们有一个 android java 客户端和一个 C++ 服务器,我们自然会用 C (facepalm) 标记它。具有讽刺意味的是,它看起来确实是 C 代码,所以 C++ 的来源是个谜。顺便说一句,您的main() 中的独立gul[200]; 的目的是什么?
  • ya ..我的错误......它是一个 c 服务器而不是 c++ 并且已经编辑了代码......它没有 gul[200]。此代码能够与 c 服务器连接并发送一个字符串。但是 android 客户端没有收到在这种情况下由变量“g”给出的响应。
  • I am able to send the string to the android client from C server.。好吧,如果服务器可以发送它,那么客户端就会接收它。那么问题是什么?你能更好地描述你的场景吗?
  • @greenapps ...sry 输入错误。我能够将字符串从 android 客户端发送到 c 服务器。但我没有得到从 c 服务器到 android 客户端的响应。

标签: android c sockets


【解决方案1】:
 String read = input.readLine();

客户端尝试读取一行。但是服务器没有发送一行

n = write(newsockfd, g,p);

在发送前将"\n" 添加到字符串变量g。而在确定p之前。

【讨论】:

  • 显示您的代码。并带有预定义的字符串。在你的帖子中。不在 cmets 中。
【解决方案2】:

首先,此代码仅适用于非常旧的 android 设备。现代设备不允许在主线程上联网,您必须将其移动到单独的线程中。网络上有足够多的教程可以做到这一点。

在简单地退出程序之前关闭套接字和文件等通常是一种好习惯。我不相信您会在编写的代码中遇到缓存问题,但这始终是一种风险,因此最佳实践表明,除非您故意提前终止程序 (exit(1)),否则您应该 close(newsockfd)

您看到的错误的最可能原因是BufferedReader.readline() 期望在每一行的末尾都有一个行终止符 (\n) 而您没有发送一个...来自内存gets()不包括用户按“回车”时的行终止符。

在这种假设下,您需要做一些事情来发送行终止符。在发送之前修改您的字符串或单独发送:

n = write(newsockfd, "\n", sizeof("\n") - 1);

不要忘记,您应该在每次写入和读取后检查响应。写入也可能失败:

if (n < 0) {
  perror("ERROR writing from socket");
  exit(1);
}

// ...

close(newsockfd);

如果您尝试了所有这些,但仍然无法正常工作...

查看双方的输出,确保它们没有打印任何错误。到目前为止,我们对您的回复都是基于“不工作”意味着它挂起的假设。如果任何一方都列出了错误,它将更清楚地说明正在发生的事情。

如果它只是挂起,那么我建议您在 C 中构建一个简单的测试客户端。这样您可以显示它仅在 C 中工作或不工作......因此您可以显示 C 代码或安卓代码不工作。如果您能找出问题所在的技术,您总会得到更多帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多