2011-01-11 5 views
0

Работа над созданием серверной/клиентской системы в C прямо сейчас, и у меня небольшие проблемы с клиентской частью. Из того, что я видел, мне нужно использовать sockaddr_in, чтобы я мог подключиться к серверу. Тем не менее, я получаю segfault каждый раз. Я считаю, что 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, так что это так же, как я могу понять ... может кто-нибудь сказать мне путь, о ликвидации Segfault?

Спасибо!

ответ

6

Быстрый комментарий:

данных является указателем на символ, который не указывает на выделенную память, так:

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

недействителен! Вы не можете разыменовать указатель NULL.

Кроме того, чтения возвращает ssize_t, а не символ, поэтому, возможно:

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

, а затем распечатать nread с printf.

2

Один немедленно очевидная вещь это неправильный принимает sizeof &addr когда вы имеете в виду sizeof addr. Также вы никогда не устанавливаете адрес, к которому хотите подключиться, только порт. В большинстве систем ни одна из этих ошибок не приведет к сбою, но они будут препятствовать работе программы.

Также рекомендуется не устанавливать sockaddr структуры напрямую, а вместо этого использовать getaddrinfo.

+0

Поскольку у меня не было времени написать правильный ответ, я добавлю некоторые ошибки здесь: 'struct sockaddr_in addr;' не инициализирован, а самое главное IP-адрес для подключения к нему не установлен. '* data = read (con, buf, 100);' dereferences указатель NULL, и типы тоже не совпадают. 'connect/write/read' должен быть проверен на наличие ошибок (и, вероятно, сколько они действительно читали или писали) – nos

0

Проблема, о которой я думаю, лежит в вашем заявлении о соединении. Вам необходимо

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

sizeof() возвращает размер объекта. Я не знаю, каков размер структуры addr, но оператор sizeof (& addr) вернет 4 (предположим 32-битную систему), и я уверен, что размер структуры addr составляет> 4 байта.

& является ссылочным оператором (или адресом) и дает вам адрес определенной структуры. Адрес (в 32-битных системах) - 4 байта. Обычно типы функций (например, функция подключения) требуют фактического размера структуры. Это часто делается для обратной совместимости, поэтому, если размер структуры изменяется в какой-либо будущей версии SDK или библиотеки, более старый код не нуждается в изменении, чтобы работать с более новыми библиотеками.

+0

er, на самом деле, я забыл изменить это. Я добавил & just, чтобы увидеть, что произойдет (ничего), и я думаю, что я не удалял его перед публикацией здесь. Даже без & все еще вызывает segfault – Curlystraw

+1

Хорошо, ну, другая проблема связана с линией * data = read (...) (и/или следующая строка) read() возвращает количество считанных байтов сокета - он не возвращает данные, считанные. Данные из сокета возвращаются в «buf». Вы, вероятно, хотите что-то вроде int num_read = read (con, buf, 100); ставит (BUF); На самом деле, вы должны проверить num_read, чтобы убедиться, что это> 0, чтобы убедиться, что вы читаете данные сокета. И вам нужно убедиться, что вы прочитали NULL, если вы собираетесь его распечатать – Mark

+0

Я вижу, я не знал, что функция read вернула байты данных! Это помогает совсем немного, спасибо! – Curlystraw

Смежные вопросы