使用gdb tcpserv学习套接字编程,选择函数总是返回1,我不知道原因。不擅长英语,所以我把代码粘贴在这里。有人帮忙吗?
文件: sockheader.h er.h内容:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <sys/select.h>
#define SERV_PORT 11211
#define SA struct sockaddr
#define LISTENQ 5
#define MAXLINE 1024
typedef void Sigfun(int);
int Socket(int family, int type, int protocol);
int Bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
int Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr *chiaddr, socklen_t *addrlen);
int Close(int sockfd);
int Connect(int sockfd, const struct sockaddr *sa, socklen_t salen);
void Writen(int sockfd, char *writeline, int len);
int str_echo(int sockfd);
int str_echo2sum(int sockfd);
int str_cli(int sockfd);
void sig_chld(int signo);文件: sockheader.c er.c内容:
#include "sockheader.h"
int Socket(int family, int type, int protocol)
{
int fd;
if( (fd = socket(family, type, protocol)) < 0 )
{
perror("socket error!\n");
exit(-1);
}
return fd;
}
int Bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
{
int bindfd;
if( (bindfd = bind(sockfd, myaddr, addrlen)) < 0 )
{
perror("bind error");
exit(-1);
}
return bindfd;
}
int Listen(int sockfd, int backlog)
{
int res ;
if( (res = listen(sockfd, backlog) ) < 0 )
{
perror("Listen error");
exit(-1);
}
return res;
}
int Accept(int sockfd, struct sockaddr *chiaddr, socklen_t *addrlen)
{
int res ;
if( (res = accept(sockfd, chiaddr, addrlen)) < 0 )
{
perror("accept error");
exit(-1);
}
return res;
}
int Close(int sockfd)
{
close(sockfd);
}
int Connect(int sockfd, const struct sockaddr *sa, socklen_t salen)
{
int res ;
if ( (res = connect(sockfd, sa, salen)) < 0)
perror("connect error");
return res;
}
void Writen(int sockfd, char *writeline, int len)
{
write(sockfd, writeline, len);
}
int str_echo(int sockfd)
{
char readline[MAXLINE];
char sendline[MAXLINE];
int n;
again:
while( (n = read(sockfd, readline, MAXLINE)) > 0 )
{
fputs("read str:\n", stdout);
readline[n] = '\0';
strcpy(sendline, "recive str:");
strcat(sendline, readline);
Writen(sockfd, sendline, strlen(sendline) + 1);
if(fputs(readline, stdout) == EOF)
{
perror("fputs error");
}
}
fputs("out while\n", stdout);
if (n < 0 )
goto again;
}
int str_echo2sum(int sockfd)
{
long arg1, arg2;
char readline[MAXLINE];
int n;
again:
while( (n = read(sockfd, readline, MAXLINE)) > 0 )
{
if( sscanf(readline, "%ld%ld", &arg1, &arg2) == 2 )
{
snprintf(readline, sizeof(readline), "%ld\n", arg1 + arg2);
}
else
{
snprintf(readline, sizeof(readline), "input error\n");
}
n = strlen(readline);
Writen(sockfd, readline, strlen(readline) + 1);
if(fputs(readline, stdout) == EOF)
{
perror("fputs error");
}
}
fputs("out while\n", stdout);
if (n < 0 )
goto again;
}
int str_cli(int sockfd)
{
char charline[MAXLINE], recvline[MAXLINE];
while(fgets(charline, MAXLINE, stdin) != NULL)
{
fputs("write string\n", stdout);
Writen(sockfd, charline, strlen(charline) + 1);
if(read(sockfd, recvline, MAXLINE) == 0)
{
perror("str_cli:server terminated prematurely");
}
if(fputs(recvline, stdout) == EOF)
{
perror("fputs error");
}
}
fputs("cli:out while\n", stdout);
}
int str_cli2(int sockfd)
{
int maxfd1, stdineof;
fd_set rset;
char buf[MAXLINE];
int n;
stdineof = 0;
FD_ZERO(&rset);
for(;;)
{
if(stdineof == 0)
{
FD_SET(fileno(stdin), &rset);
}
FD_SET(sockfd, &rset);
maxfd1 = fileno(stdin) > sockfd ? fileno(stdin) + 1 : sockfd + 1 ;
select(maxfd1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset))
{
if( ( n = read(sockfd, buf, MAXLINE) ) == 0)
{
if(stdineof == 1)
{
return ;
}
else
{
perror("str_cli2:server terminated ");
exit(-1);
}
}
Writen(fileno(stdout), buf, n );
}
if( FD_ISSET(fileno(stdin), &rset) )
{
if( ( n = read(stdin, buf, MAXLINE) ) == 0)
{
stdineof = 1;
shutdown(sockfd, SHUT_WR);
FD_CLR(fileno(stdin), &rset);
continue;
}
Writen(sockfd, buf, n);
}
}
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
{
printf("child %d terminated\n", pid);
}
return;
}文件:tcpcli05.c内容:
#include "sockheader.h"
int main(int argc, char const *argv[])
{
int sockfd, i;
struct sockaddr_in cliaddr;
for(i = 0; i < 5; i++)
{
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &cliaddr.sin_addr.s_addr);
Connect(sockfd, (SA *)&cliaddr, sizeof(cliaddr));
}
str_cli2(sockfd);
return 0;
}文件:tcpserv05.c内容:
#include "sockheader.h"
int main(int argc, char const *argv[])
{
int i, maxi, maxfd, listenfd, sockfd, connfd;
int nready, client[FD_SETSIZE];
ssize_t n ;
fd_set rset, allset;
char buf[MAXLINE];
struct sockaddr_in servaddr, chiladdr;
socklen_t chlien;
pid_t pid;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// inet_pton(AF_INET, INADDR_ANY, &servaddr.sin_addr);
Bind(sockfd, (SA *)&servaddr, sizeof(servaddr));
Listen(sockfd, LISTENQ);
// signal(SIGCHLD, sig_chld);
maxfd = sockfd;
maxi = -1;
for(i = 0; i < FD_SETSIZE; i++)
{
client[i] = -1;
}
FD_ZERO(&allset);
FD_SET(sockfd, &allset);
for(;;)
{
rset = allset;
printf("i walk here \n");
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
printf("nready:%d\n", nready);
if(FD_ISSET(sockfd, &rset))
{
chlien = sizeof(chiladdr);
if(( connfd = Accept(sockfd, (SA *)&chiladdr, &chlien )) < 0)
{
perror("accept error");
}
printf("new client: %d\n", inet_ntoa(chiladdr.sin_addr));
printf("new client port: %d\n", ntohs(chiladdr.sin_port));
for(i = 0; i < FD_SETSIZE; i++)
{
if(client[i] < 0)
{
client[i] = connfd;
break;
}
}
if(i == FD_SETSIZE)
{
perror("too many clients");
}
printf("connfd: %d\n", connfd);
FD_SET(connfd, &allset);
if(connfd > maxfd)
{
maxfd = connfd;
}
if(i > maxi)
{
maxi = i;
}
if(--nready <= 0 )
{
continue;
}
}
printf("i walk down here \n");
for( i = 0 ; i <= maxi; i++)
{
if( (listenfd = client[i]) < 0)
{
continue;
}
if(FD_ISSET(listenfd, &rset))
{
if( (n = read(listenfd, buf, MAXLINE)) == 0 )
{
Close(listenfd);
FD_CLR(listenfd, &allset);
client[i] = -1;
}
else
{
Writen(listenfd, buf, n);
}
if( --nready < 0 )
{
continue;
}
}
}
}
return 0;
}然后
gcc -o tcpserv05 -g sockheader.c tcpserv05.c
gcc -o tcpcli05 -g sockheader.c tcpcli05.c
./tcpserv05
./tcpcli05 127.0.0.1在cli中,我输入了“嗨,测试”之类的内容。服务生什么也不回。然后我在gdb tcpserv05中发现nready总是1。所以--nready <= 0是真的,继续。程序没有转到下面。
我需要帮助,首先谢谢你。
我发现了问题所在。
我写错了代码:
阅读(stdin,buf,MAXLINE)
stdin是文件*,fread、fwrite、fclose将使用stdin。
ssize_t读(int fd,buf *buf,size_t计数);
因此,我使用fileno(stdin)代替,程序工作。
发布于 2014-07-09 10:46:58
select返回1,因为这是具有事件的文件描述符的数量。如果您有一个超时,它将返回0,如果更多的文件描述符有事件,它将返回一个更高的数字。
发布于 2014-07-09 10:20:29
您可能希望使用民意测验(2)而不是旧的选择(2)。阅读关于C10K问题的文章。
因为select可以修改它的fd_set位掩码,所以您应该在循环中设置它们(通常,fd_set只是一个数组,所以分配rset = allset;不做您想做的事情)。
不要忘记在适当的地方打电话给弗卢什(3) (例如,在任何select或poll之前的fflush(NULL) )。
还可以考虑使用斯特拉斯(1)进行调试。
始终测试每个系统(2)是否失败(使用perror)
参见关于这个相关的问题的评论。
始终使用gcc -Wall -Wextra -g编译,并改进源代码,直到您完全没有收到警告。顺便说一句,bzero(3)是显式的废弃(即过时的),您不应该使用它。
https://stackoverflow.com/questions/24650549
复制相似问题