當我將BUF_SIZE設置爲10000時正常,但50000不正常。 我只是試圖從客戶端發送數據到服務器並測試緩衝區大小,但我發現在某些大小的情況下,應用程序無法正常工作。爲什麼這個緩衝區大小沒有被socket正確處理?
爲什麼?我怎麼能解決它?
例如,我運行服務器和客戶端,第一次嘗試正常工作,但是當我重新運行客戶端時,開始交付問題。
這裏是服務器:
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <signal.h>
#define BUF_SIZE 50000
using namespace std;
void manejador(int signo);
int main()
{
int sservice, sclient,l,nbytes_read, err, nbytes_sent;
bool end;
char buf[BUF_SIZE];
struct sockaddr_in sin, clientfsin;
pid_t pid;
int status;
sservice=socket(PF_INET,SOCK_STREAM, 0); /*Open the socket*/
if(sservice == -1)
{
perror("Server. Socket: ");
exit(-1);
}
sin.sin_family = AF_INET; /*ARPANET address family*/
sin.sin_addr.s_addr = INADDR_ANY; /*Accept connections on any Interface*/
sin.sin_port = htons(4000); /*Service TSAP > 1023. CHANGE IT!*/
/*Register the server in the system*/
err=bind(sservice, (struct sockaddr*)&sin, sizeof(sin));
if(err == -1)
{
perror("Server. bind: ");
exit(-1);
}
/*Up to 5 waiting connections*/
err = listen(sservice,5);
if(err == -1)
{
perror("Server. Listen: ");
exit(-1);
}
/* Receiving requests loop */
for(;;)
{
/*Accept a connection from a client*/
l = sizeof(clientfsin);
sclient = accept(sservice,(struct sockaddr *)&clientfsin, (socklen_t*) &l);
if(sclient == -1)
{
perror("Server. Accept: ");
continue;
}
signal(SIGCHLD,manejador); //Quitar si ponemos waitpid
pid = fork();
if(pid == -1){
printf("Error al crear el proceso hijo\n");
exit(0);
}
if(pid){
close(sclient);
//waitpid(pid,&status,0); //Descomentar si usamos waitpid
}else{
close(sservice);
/*Give the service*/
end = false;
int i=1;
while(!end && (i<=10))
{
nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
if (nbytes_read > 0)
{
buf[nbytes_read]='\0';
//cout << "SERVER>Server received: " << buf << endl;
printf("Recepcion <%i>: Se han recibido <%i> bytes del cliente\n",i,nbytes_read);
cout.flush();
err = 0;
//sprintf(buf,"%s_server",buf);
nbytes_sent = send(sclient,(char *)buf,sizeof(buf),0);
printf("Envio <%i>: Se han enviado <%i> bytes al cliente\n",i,nbytes_sent);
i++;
}
else
{
perror("Sever. Receive/read: ");
end=true;
err = -1;
}
}
if(err >= 0)
cout << "SERVER>Cliente Atendido" << endl;
else
cout << "SERVER>Finalizacion incorrecta del cliente" << endl;
/*Never forget to close a socket!*/
close(sclient);
exit(0);
}
}
close(sservice);
printf("Fin server");
} /*main()*/
void manejador(int signo) //comentar si usamos waitpid
{
int estado;
wait(&estado);
}
這裏是客戶端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sys/time.h>
#define BUF_SIZE 50000
using namespace std;
int main()
{
int sock, err;
bool end;
char buf[BUF_SIZE];
struct sockaddr_in sout;
sock=socket(PF_INET,SOCK_STREAM, 0); /*Open the socket*/
if(sock == -1)
{
perror("Client. Socket: ");
exit(-1);
}
sout.sin_family = AF_INET; /*ARPANET address family*/
sout.sin_addr.s_addr = inet_addr("127.0.0.1"); /*Which server?*/
sout.sin_port = htons(4000); /*Output port*/
/*Connect to the server*/
err = connect(sock,(struct sockaddr *)&sout, sizeof(sout));
if(err == -1)
{
perror("Client. Connect: ");
exit(-1);
}
end = false;
double t1,t2;
while(!end)
{
/*Ask for the service*/
//cout << endl << "CLIENT> Send a message...: " ; cout.flush();
//cin.getline(buf, 128);
int i=0;
for(i=0;i<10;i++){
timeval tim;
gettimeofday(&tim, NULL);
t1=tim.tv_sec+(tim.tv_usec/1000000.0);
err = send(sock,(char *)buf,sizeof(buf),0);
if(err == -1)
{
perror("Client. Send/write: ");
exit(-1);
}
printf("Envio <%i>: Se han enviado <%i> bytes\n",i+1,err);
gettimeofday(&tim, NULL);
t2=tim.tv_sec+(tim.tv_usec/1000000.0);
printf("%.6lf para el envio de <%i>\n", t2-t1,i+1);
err = recv(sock,(char *)buf,sizeof(buf),0);
printf("Recepcion <%i>: Se han recibido <%i> bytes\n",i+1,err);
//cout << "CLIENT> Server response: " << buf;
cout.flush();
}
end=true;
}
close(sock);
} /*main()*/
Offtopic:對不起,在西班牙的意見;)
我不確定我是否正確,但TCP連接通常會發送大小爲1500字節(由於以太網連接限制/標準)的數據包。爲什麼你需要發送50000字節的數據包?你爲什麼不把小包分成小塊呢? –
你的意思是「應用程序無法正常工作」。請進一步解釋錯誤。 – vz0
在該行'nbytes_sent = send(sclient,(char *)buf,sizeof(buf),0);'你試圖將*整個*緩衝區發送回客戶端。我認爲它應該是'nbytes_sent = send(sclient,(char *)buf,nbytes_read,0);'而不是。 – vstm