【问题标题】:It works on Debian 5.0 but it cause segmentation fault on ubuntu 11.10它适用于 Debian 5.0,但在 ubuntu 11.10 上会导致分段错误
【发布时间】:2012-01-22 17:52:33
【问题描述】:


我希望我不会收到大量垃圾问题的消息。我真的试图找出问题出在哪里,但我不知道为什么这适用于一个 linux 并导致其他 linux 上的分段错误。因此,当我在 1 号计算机上运行它时,它工作正常,但是当我在 2 号计算机上运行它时,它会导致分段错误,并收到消息 SIGSEGV。

1 号计算机有配置:
cat /etc/issue 获取:Debian GNU/Linux 5.0
uname -a get: Linux eryx2 2.6.34.4servgs #3 SMP Sun Aug 22 00:38:18 CEST 2010 i686 GNU/Linux
二号计算机有配置:
cat /etc/issue 获取:Ubuntu 11.10
uname -a 获取:Linux ubuntu 3.0.0-15-generic #25-Ubuntu SMP Mon Jan 2 17:44:42 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

我附上我的应用程序代码。
1.我运行服务器 - 好的
2.我运行客户端
3.客户端向服务器发送消息
4.服务器尝试从服务器接收消息,导致分段错误

但是这个问题只出现在 Ubuntu 上,当我在我指定的第一台计算机上运行它时它可以正常工作。

我也建立了相应的。在每个系统上编译源代码。

服务器:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

int sendMessage(char* msg, int socket){
    int length = strlen(msg);
    int ret;

    ret = write(socket, msg, length);
    return ret;
}

int readLine(void *vptr, size_t maxlen, int sockd) {
    int n, rc;
    char    c, *buffer;

    buffer = vptr;

    for ( n = 1; n < maxlen; n++ ) {

        if ( (rc = read(sockd, &c, 1)) == 1 ) {
            *buffer++ = c;
            if ( c == '\n' )
                break;
        }
        else if ( rc == 0 ) {
            if ( n == 1 )
                return 0;
            else
                break;
        }

    }

    *buffer = 0;
    return n;
}

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;


    server_sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    server_address.sin_port = htons( 10000 );

    server_len = sizeof( server_address );

        if( bind( server_sockfd, ( struct sockaddr *)&server_address, server_len ) != 0 )
        {
                perror("oops: server-tcp-single");
                exit( 1 );
        }

    listen( server_sockfd, 5 );

    signal( SIGCHLD, SIG_IGN );

    while( 1 )
    {
        char ch;

        printf( "server wait...\n" );

        client_len = sizeof( client_address );
        client_sockfd = accept( server_sockfd, ( struct sockaddr *)&client_address, &client_len );

        printf( "Connected client from %s\n", inet_ntoa( client_address.sin_addr) );

        if( fork() == 0 )
        {
            char retezec[20];
            readLine(retezec, 20, client_sockfd);

            printf( "Klient sent : %s\n", retezec );
            printf( "Server sends : %s\n", retezec );
            sendMessage(retezec, client_sockfd);
                close( client_sockfd );

            exit (0 );
        }
        else
            close( client_sockfd );

    }
}

客户

import java.io.*;
import java.net.*;

class clientTCP
{
    private static PrintWriter pw;
    private static BufferedReader br;

    private static void sendToServer(String msg) {
          try 
      {
                pw.println(msg);
                //System.out.println(msg);
                System.out.println("Klient poslal: " + msg);
            } 
      catch (Exception e)
      {
            // System.out.println("e.Message");
          }
    }

    private static String recieveFromServer() {
        String msg = "Chyba";
        try
      {
                msg = br.readLine();
              //System.out.println(msg);
              System.out.println("Klient prijal: " + msg);
        }
      catch (Exception e)
      {
                System.out.println("Selhalo prijimani zpravy zpravy!");
                //System.out.println(e.Message);
       }
       return msg;
    }

 public static void main(String argv[]) throws Exception
 {
  Socket socket = new Socket("127.0.0.1", 10000);
  InetAddress adresa = socket.getInetAddress();
  System.out.print("Pripojuju se na : "+adresa.getHostAddress()+" se jmenem : "+adresa.getHostName()+"\n" );

  pw = new PrintWriter(socket.getOutputStream(), true);
    br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  sendToServer("ahoj\n");
  String message = recieveFromServer(); 
  //System.out.println("Message Received: " + message);
  socket.close();
 }
}

谢谢。

编辑的 java 和 gcc 版本:

第一台电脑 Debian:
java版本“1.6.0_20”
Java(TM) SE 运行时环境(内部版本 1.6.0_20-b02)
Java HotSpot(TM) 服务器虚拟机(内部版本 16.3-b01,混合模式)

gcc 版本 4.3.2 (Debian 4.3.2-1.1)

第二台电脑 Ubuntu
java版本“1.6.0_26”
Java(TM) SE 运行时环境(内部版本 1.6.0_26-b03)
Java HotSpot(TM) 64 位服务器 VM(内部版本 20.1-b02,混合模式)

gcc 版本 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

编辑:通过讨论和谷歌搜索解决了问题
所以我正在添加更改,它可能会帮助有类似问题的人。
服务器中有几个问题: 而不是

int server_len, client_len;

我应该使用 socklen_t str_len, client_len;
然后代替这个(这是分段错误的原因): printf("从 %s\n 连接的客户端", inet_ntoa(client_address.sin_addr)); 我应该使用函数 inet_ntop 因为我发现 inet_ntoa 已弃用。 段错误的原因是我使用 %s 所以 printf 的 arg 是预期的 char * 这是更好的解决方案,我希望也清楚。

char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET,&(client_address.sin_addr), str, INET_ADDRSTRLEN);
printf( "Connected client from %s\n", str );

我不知道这个问题是什么,因为我在 cmets 和我的工作中得到了很好的答案。 所以我至少添加了解决问题所需的修复程序。

【问题讨论】:

  • 两台机器上Java和gcc的版本是什么?
  • 请帮自己一个忙,修复-Wall编译C代码时指出的所有问题。
  • 你能告诉我们段错误发生在哪里吗?当您使用调试器加载核心转储时,您会看到什么?
  • 我在问题的末尾添加了 java 和 gcc 版本。
  • -Wall 是告诉 GCC 输出警告的编译器标志。警告突出显示的代码问题之一是您“修复”的错误。修复其他的,并删除你对那个演员所做的“修复”,这不好。

标签: java c sockets segmentation-fault


【解决方案1】:

我会确保你总是在最后设置\0。你有一个return 0,调用者会忽略它。这意味着如果 char[] 数组中没有 \0 字节,您可能会遇到段错误。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。这是因为你没有包含

    #include <arpa/inet.h>
    

    在编译代码时会产生一个隐式声明。隐式声明方法总是返回其他类型的 int instread(如 char *)。

    段错误时

    printf("从 %s\n 连接的客户端", inet_ntoa( client_address.sin_addr) );

    因为inet_ntoa()返回一个地址并被转换为0xffffffffef7dde20,这是越界了。 inet_ntoa 的返回值被视为 32 位 int。

    你用inet_ntop解决了你的问题,不是因为inet_ntop是解决方案,如果你使用inet_ntop的返回值作为printf的参数,你仍然会得到一个段错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      相关资源
      最近更新 更多