【发布时间】: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