2011-01-11 5 views
0

Cでサーバ/クライアントシステムを作成しようとしていますが、クライアントの部分で少し問題があります。私が見たことから、サーバーに接続できるようにsockaddr_inを使用する必要があります。しかし、私は毎回セグメンテーションを受けてきました。私はsockaddr_inがそれと関係があると信じています。そして、それはプログラムの後の参照でsegfaultを修正します。sockaddr_inはsegfaultを引き起こしますか?

コード:

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

int main(int argc, char** argv) 
{ 
int Csock; 
int con; 
char *data = 0; 
char buf[101] = ""; 
struct sockaddr_in addr; 

Csock = socket(AF_INET, SOCK_STREAM, 0); 

addr.sin_family = AF_INET; 
addr.sin_port = htons(3435); 

con = connect(Csock, (struct sockaddr*) &addr, sizeof(addr)); 

write(con, "Text", sizeof("Text")); 
*data = read(con, buf, 100); 
puts(data); 
return 0; 
} 

悲しいことに、私はCにかなり新しいですので、それは私が理解することができますできるだけ多くの...誰も私にセグメンテーションフォルトを排除することについて移動するための方法を伝えることができますか?

ありがとうございます!

答えて

6

クイックコメント:

データには、割り当てられたメモリを指していないcharへのポインタです:

*data = read(con, buf, 100); 

が無効です!あなたはNULLポインタを逆参照することはできません。

ssize_t nread = read(con, buf, 100); 

を、次いでprintfとNREADを印刷:

また、ので、おそらく、戻りssize_tはなく、文字を読み取ります。

2

間違っているのは、sizeof addrの場合はsizeof &addrです。また、接続したいアドレスは設定せず、ポートだけを設定します。ほとんどのシステムでは、これらのエラーのどちらもクラッシュすることはありませんが、プログラムが動作しないようにします。

また、sockaddr構造を直接設定することはお勧めしませんが、代わりにgetaddrinfoを使用することをお勧めします。

+0

私は適切な答えを書く時間がなかったので、ここでいくつかのエラーを追加します: 'struct sockaddr_in addr;'は初期化されていません、最も重要なのは接続するIPアドレスが設定されていないことです。 '* data = read(con、buf、100);' NULLポインタを逆参照し、その型も同じではない。 'connect/write/read'はエラーをチェックするべきです(実際にどれくらい読み書きしたか) – nos

0

私が思う問題は、connectステートメントにあります。必要なのは

con = connect(Csock, (struct sockaddr*) &addr, sizeof(addr)); 

sizeof()はオブジェクトのサイズを返します。私は、addr構造体のサイズを知っているわけではありませんが、sizeof(& addr)ステートメントは4(32ビットシステムを想定)を返します。そして、私はaddr構造体のサイズが> 4バイトであると確信しています。

&は参照演算子(またはのアドレス)で、特定の構造体のアドレスを示します。アドレス(32ビットシステム)は4バイトです。通常、関数の型(connect関数のような)は構造の実際のサイズを必要とします。これは後方互換性のために行われることが多いため、SDKまたはライブラリの将来のバージョンで構造体のサイズが変更された場合、新しいライブラリを使用するために古いコードを変更する必要はありません。

+0

私は実際にそれを忘れてしまいました。私は何が起こるかを見るために&を追加しました。そして、私はここに投稿する前にそれを削除しなかったと思います。 &がなくてもセグメンテーションが発生します – Curlystraw

+1

さて、もう一つの問題は、* data = read(...)(および/または次の行)read()は、ソケットから読み込んだバイト数を返します。読み込まれたデータは返されません。ソケットからのデータは "buf"に返されます。あなたはおそらくintのような何かをしたいでしょう。num_read = read(con、buf、100); puts(buf);実際には、num_readをチェックして、ソケットのデータを確実に読み取るために0より大きいことを確認する必要があります。そして、あなたが読んだものが、それを印刷しようとしているなら、NULLで終わるかどうかを確認する必要があります。 – Mark

+0

私は、read関数がデータのバイトを返したことに気づいていませんでした!それはかなり助けてくれてありがとう! – Curlystraw

関連する問題