套接字编程:TCP 白天服务器?
Socket Programming: TCP daytime server?
我正在尝试实现一个简单的 TCP 白天服务器
这是我写的代码:-
服务器代码:-
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/ioctl.h>
#include<time.h>
int main()
{
time_t clock;
char buf[256];
int server_sockfd,client_sockfd;
int server_len;
socklen_t client_len;
struct sockaddr_in servadd;
struct sockaddr_in cliadd;
int result;
fd_set readfds,testfds;
server_sockfd=socket(AF_INET,SOCK_STREAM,0);
servadd.sin_family=AF_INET;
servadd.sin_addr.s_addr=inet_addr("127.0.0.1");
servadd.sin_port=htons(10205);
server_len=sizeof(servadd);
bind(server_sockfd,(struct sockaddr *)&servadd,server_len);
listen(server_sockfd,5);
FD_ZERO(&readfds);
FD_SET(server_sockfd,&readfds);
while(1)
{
char ch;
int fd,nread;
testfds=readfds;
printf("\n SERVER WAITING \n");
result=select(FD_SETSIZE,&testfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0);
if(result<1)
{
perror("Server error");
exit(1);
}
for(fd=0;fd<FD_SETSIZE;fd++)
{
if(FD_ISSET(fd,&testfds))
{
if(fd==server_sockfd)
{
client_len=sizeof(cliadd);
client_sockfd=accept(server_sockfd,(struct sockaddr *)&cliadd,&client_len);
FD_SET(client_sockfd,&readfds);
printf("\n Adding client on fd %d \n",client_sockfd);
}
else
{
clock=time(NULL);
sleep(5);
printf("\n Serving client on fd %d \n",fd);
snprintf(buf,sizeof(buf),"%.24s\r\n",ctime(&clock));
//ch++;
write(fd,buf,strlen(buf));
}
}
}
}
}
客户代码:-
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>
#include<string.h>
int main()
{
int createsocket=0,n=0;
char pacr[1024];
struct sockaddr_in ipos;
memset(pacr,'0',sizeof(pacr));
if((createsocket=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("\n Socket not created \n");
//return 1;
}
ipos.sin_family=AF_INET;
ipos.sin_port=htons(10205);
ipos.sin_addr.s_addr=inet_addr("127.0.0.1");
if(connect(createsocket,(struct sockaddr *)&ipos,sizeof(ipos))<0)
{
printf("\n Connection failed \n");
}
while((n=read(createsocket,pacr,sizeof(pacr)-1))>0)
{
pacr[n]=0;
if(fputs(pacr,stdout)==EOF)
{
printf("\n Standard output error \n");
}
printf("\n");
}
if(n<0)
{
printf("Standard inp error\n");
}
// return 0;
}
我没有在客户端获得所需的输出。它没有打印任何东西。我该如何解决这个问题?
日期和时间应该在客户端打印,服务器应该能够处理多个客户端。
与 fwrite
不同,write
不保证写入您传递的所有内容。因此,您可能面临的一个问题是,您在服务器上的 write
调用在第一次尝试时根本没有向套接字写入任何内容(例如,returns 0)。
特别是因为您没有使用 select
的写集。您不知道您的客户端套接字是否准备好接受写入。
要解决这个问题,您可能需要为您当前服务的每个客户保留一个结构。这种结构可能类似于
struct _active_connection
{
char to_send[1024];
size_t amt_sent;
} my_connections[FD_SETSIZE];
然后,在接受连接后,您将 FD_SET
新套接字的描述符放入 writefds
fd_set
结构中,您可以在遍历所有的相同循环中检查该结构FD_SETSIZE。
这样你就可以保持你目前的扫描所有 FD_SETSIZE 的设计,但仍然跟踪任何给定客户端的待处理数据——只尝试继续写入准备好接受额外数据的客户端套接字。
客户端对 read
的一般评论相同。 return 0 是完全合法的,特别是因为您没有在客户端执行 select
来确定套接字是否有任何等待读取的内容。 (尤其是考虑到服务器中的 sleep(5)
)。无论您是否在客户端使用 select
,您都需要在 read
上迭代,直到套接字关闭(IIRC,显示为错误 return - 来自 [=18= 的代码]).这意味着您 还需要在完成写入后关闭服务器上的套接字! 以免挂起直到超时。
所以您很可能会看到您的客户端 read
return 立即读取了 0 个字节,然后客户端退出(而服务器仍在其 sleep(5)
。(您对从 read
编辑的值 return 的检查恰好错过了 returns 0 的情况。)
我正在尝试实现一个简单的 TCP 白天服务器
这是我写的代码:-
服务器代码:-
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/ioctl.h>
#include<time.h>
int main()
{
time_t clock;
char buf[256];
int server_sockfd,client_sockfd;
int server_len;
socklen_t client_len;
struct sockaddr_in servadd;
struct sockaddr_in cliadd;
int result;
fd_set readfds,testfds;
server_sockfd=socket(AF_INET,SOCK_STREAM,0);
servadd.sin_family=AF_INET;
servadd.sin_addr.s_addr=inet_addr("127.0.0.1");
servadd.sin_port=htons(10205);
server_len=sizeof(servadd);
bind(server_sockfd,(struct sockaddr *)&servadd,server_len);
listen(server_sockfd,5);
FD_ZERO(&readfds);
FD_SET(server_sockfd,&readfds);
while(1)
{
char ch;
int fd,nread;
testfds=readfds;
printf("\n SERVER WAITING \n");
result=select(FD_SETSIZE,&testfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0);
if(result<1)
{
perror("Server error");
exit(1);
}
for(fd=0;fd<FD_SETSIZE;fd++)
{
if(FD_ISSET(fd,&testfds))
{
if(fd==server_sockfd)
{
client_len=sizeof(cliadd);
client_sockfd=accept(server_sockfd,(struct sockaddr *)&cliadd,&client_len);
FD_SET(client_sockfd,&readfds);
printf("\n Adding client on fd %d \n",client_sockfd);
}
else
{
clock=time(NULL);
sleep(5);
printf("\n Serving client on fd %d \n",fd);
snprintf(buf,sizeof(buf),"%.24s\r\n",ctime(&clock));
//ch++;
write(fd,buf,strlen(buf));
}
}
}
}
}
客户代码:-
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>
#include<string.h>
int main()
{
int createsocket=0,n=0;
char pacr[1024];
struct sockaddr_in ipos;
memset(pacr,'0',sizeof(pacr));
if((createsocket=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("\n Socket not created \n");
//return 1;
}
ipos.sin_family=AF_INET;
ipos.sin_port=htons(10205);
ipos.sin_addr.s_addr=inet_addr("127.0.0.1");
if(connect(createsocket,(struct sockaddr *)&ipos,sizeof(ipos))<0)
{
printf("\n Connection failed \n");
}
while((n=read(createsocket,pacr,sizeof(pacr)-1))>0)
{
pacr[n]=0;
if(fputs(pacr,stdout)==EOF)
{
printf("\n Standard output error \n");
}
printf("\n");
}
if(n<0)
{
printf("Standard inp error\n");
}
// return 0;
}
我没有在客户端获得所需的输出。它没有打印任何东西。我该如何解决这个问题?
日期和时间应该在客户端打印,服务器应该能够处理多个客户端。
与 fwrite
不同,write
不保证写入您传递的所有内容。因此,您可能面临的一个问题是,您在服务器上的 write
调用在第一次尝试时根本没有向套接字写入任何内容(例如,returns 0)。
特别是因为您没有使用 select
的写集。您不知道您的客户端套接字是否准备好接受写入。
要解决这个问题,您可能需要为您当前服务的每个客户保留一个结构。这种结构可能类似于
struct _active_connection
{
char to_send[1024];
size_t amt_sent;
} my_connections[FD_SETSIZE];
然后,在接受连接后,您将 FD_SET
新套接字的描述符放入 writefds
fd_set
结构中,您可以在遍历所有的相同循环中检查该结构FD_SETSIZE。
这样你就可以保持你目前的扫描所有 FD_SETSIZE 的设计,但仍然跟踪任何给定客户端的待处理数据——只尝试继续写入准备好接受额外数据的客户端套接字。
客户端对 read
的一般评论相同。 return 0 是完全合法的,特别是因为您没有在客户端执行 select
来确定套接字是否有任何等待读取的内容。 (尤其是考虑到服务器中的 sleep(5)
)。无论您是否在客户端使用 select
,您都需要在 read
上迭代,直到套接字关闭(IIRC,显示为错误 return - 来自 [=18= 的代码]).这意味着您 还需要在完成写入后关闭服务器上的套接字! 以免挂起直到超时。
所以您很可能会看到您的客户端 read
return 立即读取了 0 个字节,然后客户端退出(而服务器仍在其 sleep(5)
。(您对从 read
编辑的值 return 的检查恰好错过了 returns 0 的情况。)