Не работает клиент - сервер - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Помогите найти ошибку. Надо: на сервере задано уравнение, клиент решает его методом деления пополам, запрашивая у сервера значение функции в точке. по-моему ошибка где-то в алгоритме поиска корня Клиент:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <math.h>
static void usage();
 
int sign(double x)
{
    double rez;
    if (x < 0)  rez=-1;
    else if (x==0) rez=0;
    else rez=1;
    return rez;}
 
int main(int argc,char *argv[]){
    int i;
    double a,b,c, e=0.1,fa,fb, fc, root;
    if (argc>1&&*(argv[1])==' ') {
        usage(); exit(1);
    }
    int s0=socket(AF_INET,SOCK_STREAM,0);
    if (s0<0){
        perror("can`t create a socket"); exit(1);
    }
    struct sockaddr_in peeraddr;
    memset(&peeraddr,0,sizeof(peeraddr));
    const char *peerhost="localhost";
    if(argc>1)
        peerhost=argv[1];
    struct hostent *host=gethostbyname(peerhost);
    if(host==NULL)
        {perror("cannot define host adress"); exit(1);};
    peeraddr.sin_family=AF_INET;
    short peerport=1234;
    if (argc>=3)
        peerport=(short)atoi(argv[2]);
    peeraddr.sin_port=htons(peerport);
    printf("peer addr=%d.%d.%d.%d port=%d\n",host->h_addr_list[0][0]&0xff,
                                         host->h_addr_list[0][1]&0xff,
                                         host->h_addr_list[0][2]&0xff,
                                         host->h_addr_list[0][3]&0xff,
                                         (int)peerport);
 
    memmove(&peeraddr.sin_addr.s_addr,host->h_addr_list[0],4);
    int res=connect(s0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));\
 
    if(res<0)
        {perror("can`t connect");exit(1);};
    printf("connected.reading a server message.\n");
    char buffer[1024];
    res=read(s0,buffer,1024);
    if(res<0)
        {perror("read error");exit(1);};
    printf("\n%s",buffer);
    printf("Vvedite granitsu otrezka, na kotorom bydem reshat' yravnenie");
    scanf("%f", &a);
    scanf("%f", &b);
    write(s0, &a, sizeof(double));
    write(s0, &b, sizeof(double));
    while((b-a)>e){
        c=(b-a)/2;
        write(s0, &a, sizeof(double));
        write(s0, &b, sizeof(double));
        read(s0, &fa, sizeof(double));
        read(s0, &fb, sizeof(double));
        read(s0, &fc, sizeof(double));
        if(sign(fb)==sign(fa)){
            printf("na dannom otrezke kornei ne nabludaetsa");
            return -1;}
        if(sign(fc)!=sign(fb))
           a=c;
        else b=c;}
root=(b-a)/2;
printf(" \n%f", root);
close(s0);
return 0;
}
 
static void usage(){
printf("usage: ./client [IP_addres_of_server [port_of_server]]\n");}
сервер:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <math.h>
static void usage();
 
double f(double x){
    return x*x-1;
}
 
int main(int argc,char *argv[]){
    double a,b, e=0.01;
    if(argc>1 && *(argv[1])==' ')
        {usage();exit(1);};
    int listenport=1234;
    if(argc>1)
        {listenport=atoi(argv[1]);};
    int s0=socket(AF_INET,SOCK_STREAM,0);
    if(s0<0)
        {perror("cant create a socket");exit(1);};
    struct sockaddr_in myaddr;
    memset(&myaddr,0,sizeof(struct sockaddr_in));
    myaddr.sin_family=AF_INET;
    myaddr.sin_port=htons(listenport);
    myaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    int res=bind(s0,(struct sockaddr*)&myaddr,sizeof(myaddr));
    if(res<0)
        {perror("cant bind a socket");exit(1);};
    struct linger linger_opt={1,0};
    setsockopt(s0,SOL_SOCKET,SO_LINGER,&linger_opt,sizeof(linger_opt));
    res=listen(s0,1);
    if(res<0)
        {perror("cant listen");exit(1);};
    struct sockaddr_in peeraddr;
    socklen_t peeraddr_len=sizeof(peeraddr);
    int s1=accept(s0,(struct sockaddr*)&peeraddr,&peeraddr_len);
    if(s1<0)
        {perror("cant accept");exit(1);};
    printf("connection from IP %d.%d.%d.%d , port %d\n",(htonl(peeraddr.sin_addr.s_addr)>>24)&0xff,
                                                        (htonl(peeraddr.sin_addr.s_addr)>>16)&0xff,
                                                        (htonl(peeraddr.sin_addr.s_addr)>>8)&0xff,
                                                        (htonl(peeraddr.sin_addr.s_addr)>>0)&0xff,
                                                        htons(peeraddr.sin_port));
    write(s1,"Solve x^2-1=0\n\n",17);
    res=read(s1,&a,sizeof(double));
    if(res<0)
        {perror("read error");exit(1);};
    read(s1,&b,sizeof(double));
    while((b-a)>e){
        read(s1,&a,sizeof(double));
        read(s1,&b,sizeof(double));
        
        write(s1,&f(a),sizeof(double));
        write(s1,&f(b),sizeof(double));
        write(s1,&f((b-a)/2),sizeof(double));
    }
    printf(" \n%f",(b-a)/2);
    close(s1);
    return 0;
}
 
static void usage(){
  printf("usage:\n server [port]\n");
}

Решение задачи: «Не работает клиент - сервер»

textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <math.h>
static void usage();
 
int main(int argc,char *argv[]){
    double a, b, a1, b1, c1,c, eps;
    if (argc>1&&*(argv[1])==' ') {
        usage(); exit(1);
    }
    int s0=socket(AF_INET,SOCK_STREAM,0);
    if (s0<0){
        perror("can`t create a socket"); exit(1);
    }
    struct sockaddr_in peeraddr;
    memset(&peeraddr,0,sizeof(peeraddr));
    const char *peerhost="localhost";
    if(argc>1)
        peerhost=argv[1];
    struct hostent *host=gethostbyname(peerhost);
    if(host==NULL)
        {perror("cannot define host adress"); exit(1);};
    peeraddr.sin_family=AF_INET;
    short peerport=1234;
    if (argc>=3)
        peerport=(short)atoi(argv[2]);
    peeraddr.sin_port=htons(peerport);
    printf("peer addr=%d.%d.%d.%d port=%d\n",host->h_addr_list[0][0]&0xff,
                                         host->h_addr_list[0][1]&0xff,
                                         host->h_addr_list[0][2]&0xff,
                                         host->h_addr_list[0][3]&0xff,
                                         (int)peerport);
 
    memmove(&peeraddr.sin_addr.s_addr,host->h_addr_list[0],4);
    int res=connect(s0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));\
 
    if(res<0)
        {perror("can`t connect");exit(1);};
    printf("connected.reading a server message.\n");
    char buffer[1024];
    res=read(s0,buffer,1024);
    if(res<0)
        {perror("read error");exit(1);};
    printf("\n%s",buffer);
    printf("Vvedite granitsu otrezka, na kotorom bydem reshat' yravnenie");
    scanf("%lf%lf", &a, &b);
    printf("введите точность поиска корня");
    scanf("%lf", &eps);
    write(s0, &a, sizeof(double));
    write(s0, &b, sizeof(double));
    write(s0, &eps, sizeof(double));
    if(fabs(b-a)>eps){//проблема в этом цикле
        c=(b-a)/2;
        read(s0,&a1, sizeof(double));
        read(s0,&b1, sizeof(double));
        read(s0,&c1, sizeof(double));
        if(a1==0){
            printf("root:%lf", a);
            exit(1);}
        if(b1==0){
            printf("root:%lf",b);
            exit(1);}
        if(a1*b1>0){
            printf("корней нет");}
        if(a1*c1<0){
            b=c;}
        else a=c;
        write(s0, &a, sizeof(double));
        write(s0, &b, sizeof(double));
        }
 
printf("root%lf",c);
    
close(s0);
return 0;
}
 
static void usage(){
printf("usage: ./client [IP_addres_of_server [port_of_server]]\n");}

Объяснение кода листинга программы

  1. Включаются необходимые заголовочные файлы: , , , , <sys/socket.h>, <netinet/in.h>, , .
  2. Определяется функция-обработчик ошибок usage.
  3. Создается клиентский сокет s0 с использованием socket(AF_INET, SOCK_STREAM, 0).
  4. Присваивается адрес сервера переменной peeraddr с использованием gethostbyname(peerhost).
  5. Сетевой порт сервера устанавливается в peerport с использованием htons(peerport).
  6. Выводится информация об адресе и порту сервера.
  7. Происходит попытка подключения к серверу с использованием connect(s0, (struct sockaddr*)&peeraddr, sizeof(peeraddr)).
  8. Если подключение успешно, происходит чтение сообщения от сервера в буфер buffer с использованием read(s0, buffer, 1024).
  9. Выводится полученное сообщение.
  10. Пользователю предлагается ввести границы интервала для поиска корня и точность поиска с использованием scanf(%lf%lf, &a, &b).
  11. Пользователю предлагается ввести точность поиска корня с использованием scanf(%lf, &eps).
  12. На сервер отправляются значения a, b и eps с использованием write(s0, &a, sizeof(double));, write(s0, &b, sizeof(double));, write(s0, &eps, sizeof(double));.
  13. Если разница между b и a больше заданной точности, выполняется цикл.
  14. Внутри цикла выполняются следующие действия:
    • Вычисляется промежуточная точка c как среднее между a и b.
    • Происходит чтение значений a1, b1 и c1 с сервера с использованием read(s0, &a1, sizeof(double));, read(s0, &b1, sizeof(double));, read(s0, &c1, sizeof(double));.
    • Если a1 равно нулю, выводится корень и программа завершается.
    • Если b1 равно нулю, выводится корень и программа завершается.
    • Если a1*b1 больше нуля, выводится сообщение о отсутствии корней и программа продолжает работу.
    • Если a1*c1 меньше нуля, b заменяется на c и программа продолжает работу.
    • Если a1*c1 больше нуля, a заменяется на c и программа продолжает работу.
    • На сервер отправляются обновленные значения a и b с использованием write(s0, &a, sizeof(double));, write(s0, &b, sizeof(double));.
  15. Выводится корень с использованием printf(root%lf,c).
  16. Клиентский сокет закрывается с использованием close(s0).
  17. Программа возвращает 0, что означает успешное выполнение.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5