Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Ошибка сегментирования при запуске чата написанного на си

36K
01 марта 2008 года
winall
2 / / 01.03.2008
Привет всем, вот решил написать простенький чат под linux что б мог по локальгой сетке с народ общаться, короче вот смотрите, вот сервак:
Код:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>


int GetPort(const char *str);
void Usage();
void Error(const char *msg);
void Work(int sock);

int main (int argc, char **argv)
{
int port;
int sock;
int retcode;
struct sockaddr_in sa;
if(argc!=2 || strcmp(argv[1],"-h")==0)
{
Usage();
}
port=GetPort(argv[1]);
printf("Запускаю сервер на порту %d\n",port);

sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock==-1)
{
Error ("Не могу создать сокет");
}

memset(&sa,0,sizeof(sa));
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=INADDR_ANY;
sa.sin_port=htons(port);
retcode=bind(sock,(struct sockaddr*) (&sa),sizeof(sa));
if(retcode==-1)
{
Error("Ошибка привязи сокета к ip адрусу и номкру порта");
}
retcode=listen(sock,10);
if(retcode==-1)
{
Error("Ощшибка перевода сокета в пассивное состояние");
}
Work(sock);
close(sock);
return 0;
}
int GetPort(const char *str)
{
int port;
port=atoi(str);
if(port<1||port>65535)
{
Error("Магическое число должно быть в диапозоне");
}
return port;
}
void Work(int sock)
{
fd_set ourfds;
fd_set readfds;
char buf[8192];
int len;
int retcode;
int sock2;
int sock3;
char list [1024];
socklen_t size;
struct sockaddr_in sa;

FD_ZERO(&ourfds);
while (42==42){
FD_ZERO(&readfds);
readfds=ourfds;
FD_SET(sock,&readfds);
retcode=select(FD_SETSIZE,&readfds,NULL,NULL,NULL);
if (retcode==-11)
{
Error("Ошибка select");
}
if (FD_ISSET(sock,&readfds))
{
sock2=accept(sock,(struct sockaddr*)(&sa),&size);
if (sock2==-1)
{
Error("Ошибка получения адреса пользователя");
}
printf("Приняли соединение с адреса%s\n",inet_ntoa(sa.sin_addr));
FD_SET(sock2,&ourfds);
}
for (sock=0; sock2<FD_SETSIZE;sock2++)
{
if(FD_ISSET(sock2,&ourfds) && FD_ISSET(sock2,&readfds))
{
len=read(sock2,buf,sizeof(buf));
if(len<0)
{
printf("Ошибка чтения сокета");
FD_CLR(sock2,&ourfds);
}
else if(len==0)
{
printf("Клиент %s закрыл соединение\n",inet_ntoa(sa.sin_addr));
FD_CLR(sock2,&ourfds);
}
else
{
buf[len]=0;
if(getsockname(sock,(struct sockaddr*)(&sa),&size)==-1)
{
printf("Error getsockname\n");
}
printf("Получили с адреса %s: %s\n",inet_ntoa(sa.sin_addr),buf);
if (buf[0]=='s')
{
sock3=atoi(buf+1);
write(sock3,buf,len);
}
else if (buf[0]=='l')
{
for(sock3=0; sock3<FD_SETSIZE; sock++)
{
if(FD_ISSET(sock3,&ourfds))
{
sprintf(list,"Список подключенных пользователей\n%d\n",sock3);
write(sock2,list,strlen(list));
}
}
}
else
{
sprintf(list,"Уважаемый клиент. Нет такой команды!!!\n");
write(sock,list,strlen(list));
}
}
}
}
}
}
void Usage()
{
fprintf(stderr,"Запускать как: ./server port.\n");
exit(-1);
}
void Error(const char *msg)
{
fprintf(stderr,"Ошибка: %s(%s)\n",msg,strerror(errno));
exit(-1);
}




вот клиент

Код:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>

int GetPort(const char *str);
void Usage();
void Error(const char *msg);
int Talk(int sock);

int main(int argc, char **argv)
{
int port;
int sock;
int retcode;
struct sockaddr_in servaddr;
struct hostent *host;
if(argc!=3|| strcmp(argv[1],"-h")==0)
{
Usage();
}
port=GetPort(argv[2]);
printf("Запуская клиент на порту %d\n",port);

sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if (sock==-1)
{
Error("Не могу создать сокет");
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(port);
host=gethostbyname(argv[1]);
if  (host==0)
{
Error("Не верный IP");
}
servaddr.sin_addr.s_addr=*(unsigned long*)(host->h_addr);
retcode=connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr));
if (retcode==-1)
{
Error("Ошибка подключения");
}
Talk(sock);
close(sock);
return 0;
}

int GetPort(const char *str)
{
int port;
port=atoi(str);
return port;
}

int Talk(int sock)
{
char buf[81920];
int len;
int retcode;
fd_set readfds;
while (42==42)
{
FD_ZERO(&readfds);
FD_SET(sock,&readfds);
FD_SET(0,&readfds);
retcode=select(1024,&readfds,0,0,0);
if(retcode==-1)
{
Error("Ошибка select");
}
else
{
if(FD_ISSET(sock,&readfds))
{
len=read(sock,buf,sizeof(buf));
if(len<0)
{
Error("Ошибка чтения сокета");
}
else if (len==0)
{
printf("Сервер закрыл соединение\n");
return 0;
}
else
{
buf[len]=0;
printf("Получил с сервера: %s\n",buf);
}
}
if(FD_ISSET(0,&readfds))
if(len<0)
{
Error("Ошибка чтения");
}
else if (len==0)
{
printf("Сервер закрыл соединение\n");
return 0;
}
else
{
buf[len]=0;
retcode=write(sock,buf,len);
if(retcode==-1)
{
Error("Ошибка отправки");
}
}
}
}
}





void Usage()
{
fprintf(stderr,"Запускать как ./client ip port.\n");
exit(-1);
}
void Error(const char *msg)
{
fprintf(stderr,"Ошибка:%s(%s)\n",msg,strerror(errno));
exit(-1);
}


Компилю так cc server.c и cc client.c
компилеться все на ура!!!
запускаю сервер ./a.out 123
Пишет сервер запушен на порту 1234
Запуская клинт ./client localhost 1234
Клиент запуцстился
А сервак выдает клиет подключен, но как токо ченить начинаю в клиенте писать(всмысле сообщение) выдает ошибка сегментирования! Немогу понять что это такое, читал читал на форумах и не понял, может кто у ся запустит и посмотрит. Спасибо всем!;)
1.8K
02 марта 2008 года
igor_nf
256 / / 13.12.2006
Потестить не берусь, но могу посоветовать прогнать под отладчиком(GDB) - обычно помогает найти ошибку. Компилируй с опцией -g для включения отладочной информации в объектный модуль, и используй команду step отладчика(см. man gdb).
36K
02 марта 2008 года
winall
2 / / 01.03.2008
Цитата: igor_nf
Потестить не берусь, но могу посоветовать прогнать под отладчиком(GDB) - обычно помогает найти ошибку. Компилируй с опцией -g для включения отладочной информации в объектный модуль, и используй команду step отладчика(см. man gdb).



Компилется без ошибок и проблем, а вот при запуске говорит ошибка сегментирования!

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог