2014-01-31 103 views
0

我鍵入兩個程序一個用於客戶端,一個用於服務器。 服務器是tcp併發echo服務器用select調用,以便只對所有客戶端使用一個進程。 它使用明顯的併發性。客戶端服務器編程緩衝區內容不正確

我開發程序並運行它的工作,但在3/4消息交換之後打賭客戶端和服務器。 服務器上的緩衝區內容將其更改爲顯示當前消息,其中包含以前消息中的某個字符。

我不明白爲什麼會發生這種情況。 請任何人能幫助我...

//Client Program 

#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <iostream> 
using namespace std; 

#define MAXLINE 4096 /*max text line length*/ 
#define serv_PORT 3000 /*port*/ 

int main(int argc,char **argv) 
{ 
int sockfd; 
struct sockaddr_in servaddr; 
char sendline[MAXLINE]; 
char recvline[MAXLINE]; 
/*int sendchars,recvchar; 
char buf[MAXLINE]; 
*/ 

if (argc !=2) 
{ 
    cerr<<"Usage: Femto: <IP address of the serv"<<endl; 
    exit(1); 
} 

//Create a socket for the client 

if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) 
{ 
    cerr<<"Problem in creating the socket"<<endl; 
    exit(1); 
} 

//Creation of the socket 

memset(&servaddr, 0, sizeof(servaddr)); 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr= inet_addr(argv[1]); 
servaddr.sin_port = htons(serv_PORT); 

//Connection of the client to the socket 
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) 
{ 
    cerr<<"Problem in connecting to the serv"<<endl; 
    exit(1); 
} 

while (fgets(sendline, MAXLINE, stdin) != NULL) 
{ 
    send(sockfd, sendline, strlen(sendline), 0); 
    if (recv(sockfd, recvline, MAXLINE,0) == 0) 
    { 
    cerr<<"The serv terminated"<<endl; 
    exit(1); 
    } 

    cout<< "String received from the serv: "; 
    fputs(recvline, stdout); 
} 

exit(0); 
} 


//Server program 

#include <stdlib.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <unistd.h> 
#include <iostream> 
#include <sys/select.h> 
#include <sys/time.h> 


using namespace std; 
#define MAXLINE 4096 /*max text line length*/ 
#define serv_PORT 3000 /*port*/ 
#define LISTENQ 65535 

int main (int argc, char **argv) 
{ 
int msock,ssock; 
fd_set rfds; 
fd_set afds; 
int fd,nfds; 
socklen_t client_len ; 


char buf[MAXLINE]; 
struct sockaddr_in clientaddr, servaddr; 

if ((msock = socket (AF_INET, SOCK_STREAM, 0)) <0) 
{ 
cerr<<"Problem in creating the socket"<<endl; 
exit(1); 
    } 

servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port = htons(serv_PORT); 

bind (msock, (struct sockaddr *) &servaddr, sizeof(servaddr)); 

listen (msock, LISTENQ); 

nfds=getdtablesize(); 
FD_ZERO(&afds); 
FD_SET(msock,&afds); 

while(1) 
{ 
memcpy(&rfds,&afds,sizeof(rfds)); 
if(select(nfds,&rfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0)<0) 
{ 
cerr<<"Error in select"; 
// exit(1); 
} 


if(FD_ISSET(msock,&rfds)) 
{ 
//int ssock; 
ssock= accept(msock,(struct sockaddr *)&clientaddr,&client_len); 
    if(ssock<0) 
    { 
    cerr<<"Accept error"; 
    } 
FD_SET(ssock,&afds); 
} 
int n; 
for(fd=0;fd<nfds;++fd) 
    if(fd!=msock && FD_ISSET (fd,&rfds)) 
    while ((n = recv(fd, buf, MAXLINE,0)) > 0) { 
    cout<<"String received from and resent to the client:"<<endl; 
    puts(buf); 
    send(fd, buf, n, 0); 
} 
close(fd); 
FD_CLR(fd,&afds); 
    } 
} 



output:: 

client-hi 
server-hi 

client-bye 
server-bye 

//after some message exchange 
client-wru? 
server-wru? 

client- i m here 
server-i am here u? 
+0

嘗試在每次從服務器發送數據前清除緩衝區..可能會工作:) fflush(stdout) –

+0

@AxitSoni服務器不使用stdout,因此刷新它將毫無意義,並且在發送之前清除緩衝區他們也沒有任何意義。 – EJP

回答

1

你讓忽略()的返回RECV計數的一般錯誤。緩衝區中的數據僅在該計數之前有效。其餘部分與之前的值不變。

您還忽略了bind(),listen(),send()和recv()中的錯誤的可能性。