Не работает клиент - сервер - 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");}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы:
, , , , <sys/socket.h>, <netinet/in.h>, , . - Определяется функция-обработчик ошибок
usage
. - Создается клиентский сокет
s0
с использованиемsocket(AF_INET, SOCK_STREAM, 0)
. - Присваивается адрес сервера переменной
peeraddr
с использованиемgethostbyname(peerhost)
. - Сетевой порт сервера устанавливается в
peerport
с использованиемhtons(peerport)
. - Выводится информация об адресе и порту сервера.
- Происходит попытка подключения к серверу с использованием
connect(s0, (struct sockaddr*)&peeraddr, sizeof(peeraddr))
. - Если подключение успешно, происходит чтение сообщения от сервера в буфер
buffer
с использованиемread(s0, buffer, 1024)
. - Выводится полученное сообщение.
- Пользователю предлагается ввести границы интервала для поиска корня и точность поиска с использованием
scanf(
%lf%lf, &a, &b)
. - Пользователю предлагается ввести точность поиска корня с использованием
scanf(
%lf, &eps)
. - На сервер отправляются значения
a
,b
иeps
с использованиемwrite(s0, &a, sizeof(double));
,write(s0, &b, sizeof(double));
,write(s0, &eps, sizeof(double));
. - Если разница между
b
иa
больше заданной точности, выполняется цикл. - Внутри цикла выполняются следующие действия:
- Вычисляется промежуточная точка
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));
.
- Вычисляется промежуточная точка
- Выводится корень с использованием
printf(
root%lf,c)
. - Клиентский сокет закрывается с использованием
close(s0)
. - Программа возвращает 0, что означает успешное выполнение.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д