基于linux的C网络服务器编程

基于linux的C网络服务器编程,c,linux,network-programming,C,Linux,Network Programming,我想做一个程序,这样,当客户端断开连接时,服务器将返回准备接受来自客户端的新请求。这是密码 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <u

我想做一个程序,这样,当客户端断开连接时,服务器将返回准备接受来自客户端的新请求。这是密码

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    int sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Now Time: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}
错误:从'int*'到'socklen_t*{aka unsigned int*}'[-fppermissive]的转换无效

connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
错误:初始化“int-accept(int,sockaddr*,socklen_t*)”的参数3[-fppermissive]

connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
我该怎么处理这些问题呢?指针是否正确?

使用
while(1)
而不是
while(true)
并使用C编译器而不是C++编译器

错误来自使用C++编译器编译源代码。如果您使用C编译器,您的代码不会产生上述错误,除非现在未定义
true

您需要使用

socklen_t sin_size;

更改你的申报单

 socklen_t  sin_size;  
这就解决了你的问题


您也可以尝试将此作为最后手段,但上述更改对您来说很好

修改此语句

connfd=accept(listenfd,(struct sockaddr*)和cliaddr,(socklen_t*)和sinu size)

请参见
man accept

在看到@alk comment之后,我从comment中添加了这一部分


特别是在抛出指针时,它可能只是抛出编译时错误,但在运行时可能会崩溃,因为程序在取消引用指针时所期望的大小与实际情况不同

回答正确,需要在root访问用户上运行

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    socklen_t sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Sekarang pukul: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义MAXLINE 100
#定义清单10
int main()
{
int tmp、listenfd、connfd;
袜子的大小;
servaddr、cliaddr中的结构sockaddr\u;
字符buff[MAXLINE];
时间滴答;
while(true)
{
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin\u addr.s\u addr=INADDR\u ANY;
servaddr.sinu port=htons(13);
memset(&(servaddr.sin_zero),'\0',8);
listenfd=套接字(AF_INET,SOCK_STREAM,0);
如果(listenfd==-1){
perror(“错误套接字”);
出口(1);
}
tmp=bind(listenfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
如果(tmp==-1){
perror(“错误绑定”);
出口(1);
}
tmp=侦听(listenfd,LISTENQ);
如果(tmp==-1){
perror(“错误监听”);
出口(1);
}
sin_size=sizeof(结构sockaddr_in);
connfd=accept(listenfd,(struct sockaddr*)&cliaddr和sinu size);
如果(connfd==-1){
perror(“错误接受”);
出口(1);
}
刻度=时间(空);
snprintf(buff,sizeof(buff),“Sekarang pukul:%.24s\r\n”,ctime(&ticks));
写(connfd,buff,strlen(buff));
关闭(connfd);
关闭(listenfd);
}
}

这是一个非常容易理解的错误消息。将
sin\u size
声明为
socklen\u t
。另外,请记住
#包括
@user4815162342您的意思是将sin_大小声明为socklen_t,如“int sin_size socklen_t”?@greenthunder将第16行更改为socklen_t sin_大小;应该没问题,仅此而已。小事情:
bzero
已被弃用,请使用
memset
。例如,当需要
IPv6
时,不要使用
sockaddr\u in
,使用
sockaddr\u存储
(等)使自己或其他人的生活更轻松。谢谢你记住了我。。但它仍然得到一个错误,上面写着“$demo error bind..:权限被拒绝”,那么我该怎么办?我已将while(true)更改为while(1),并保留rest@greenthunder:您需要具有根权限才能绑定到1024以下的端口。您的答案无法回答OP的问题。“这是一个注释。@greenthunder:在具有root权限的用户帐户下运行该过程。请原谅,但我真的看不出您的答案与clearley由于
sin\u size
被忽略为
int
socklen\u t
而导致的这两个错误之间有任何关系。您为什么建议强制转换,如果最直接的解决方案是将
sinu size
声明为
socklen\u t
?铸造应始终作为最后手段。事实上,这应该是最后手段。这个答案是可选的,特别是在抛出指针时,它可能会抛出编译时错误,但在运行时可能会崩溃,因为程序在取消引用指针时所期望的大小与实际情况不同。你最好删除答案的这一部分。谢谢你简洁的解释。我遇到了这个问题。在OP案例中,没有任何问题,但最好从答案中删除它。我改变了这一点,结果仍然是错误绑定,从这里“tmp=bind(listenfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))”只需使用您刚刚修复为正确类型的
sinu size