Не работает клиент - сервер - 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, что означает успешное выполнение.