2014-01-31 67 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()中的错误的可能性。