C语言中的套接字编程(客户端服务器示例)

4

我很新于Unix编程,并编写了以下客户端和服务器端编程代码。当我尝试运行客户端代码时,它会显示“连接被拒绝”错误信息。请问可能是什么原因。

服务器端代码:

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

int main(void)
{
    int sockid,newsockid;
    socklen_t addr_size;
    char *msg="What a beautiful morning!";
    int len, bytes_sent;
    sockid=socket(AF_INET,SOCK_STREAM,0);
    if(sockid==-1)
    {
        perror("socket");
        exit(1);
    }
    else
        printf("created");
    struct sockaddr_in serveraddr,clientaddr;
    bzero((char *)&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(7400);
    serveraddr.sin_addr.s_addr=INADDR_ANY;

    if(bind(sockid,(struct sockaddr *)&serveraddr,sizeof(serveraddr))<0)
    {
        perror("bind");
        return -1;
    }

    listen(sockid,5);
    addr_size=sizeof(clientaddr);
    newsockid=accept(sockid,(struct sockaddr *)&clientaddr,&addr_size);
    len = strlen(msg);
    bytes_sent = send(sockid, msg, len, 0);
    close(sockid);
}

客户端代码:

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

int main(void)
{
    int byte_count;
    struct sockaddr_in serveraddr;
    char *servername;
    char buf[256];
    socklen_t addr_size;
    int sockfd;

    sockfd=socket(AF_INET,SOCK_STREAM,0);
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(11378);
    servername=gethostbyname("localhost");
    inet_pton(AF_INET,servername,&serveraddr.sin_addr);

    addr_size=sizeof(serveraddr);
    if(connect(sockfd,(struct sockaddr *)&serveraddr,addr_size)==-1)
    {
        perror("connect");
        exit(1);
    }

    byte_count = recv(sockfd, buf, sizeof buf, 0);
    printf("recv()'d %d bytes of data in buf\n", byte_count);

    close(sockfd);
}

希望能尽早得到帮助。 谢谢。


1
仔细检查servername的初始化方式。并且:务必使用所有警告开启(对于gc,使用-Wall -Wextra -pedantic),然后修复代码,直到没有更多的警告出现! - alk
我已经做了一些更改...请忽略端口号的更改。还有其他需要我做的吗? - user2725511
存在一个概念上的问题:客户端调用 recv() 会被阻塞,因为它试图接收比服务器发送的更多的数据。 - alk
1
如果您有兴趣,我可以向您发送我的小时费率。希望能尽早得到帮助 - alk
对不起,一开始我没明白,但现在我真的卡住了,那个评论有点惹恼我了。不过,我为我的评论道歉。 - user2725511
显示剩余2条评论
4个回答

4
sockfd=socket(AF_INET,SOCK_STREAM,0);
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(7400);
inet_pton(AF_INET,servername,&serveraddr.sin_addr); // here

您正在向inet_pton()传递 servername,但它未初始化!因此inet_pton()会失败。您应该检查其返回值。

servername=gethostbyname(); //here
addr_size=sizeof(serveraddr);

第二个问题是你没有正确使用gethostbyname()函数。看一下manpage,你会发现gethostbyname()需要传入参数,并且它返回一个指向struct hostent结构体的指针,而不是像你所做的那样返回一个指向char的指针。因为你没有包含netdb.h头文件,所以编译器没有警告你这一点。
你应该检查你使用的所有函数的返回值,这可以避免出现类似的问题。你应该启用一些编译器标志(如问题评论中提到的alk-W -Wextra -Wall -pedantic是非常好的标志)。

我已经纠正了你要求我纠正的两个错误。但它仍然无法工作。再次显示“连接被拒绝”。 - user2725511
1
好的,更新后的代码如下: sockfd=socket(AF_INET,SOCK_STREAM,0); bzero(&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(11378); servername=gethostbyname("localhost"); inet_pton(AF_INET,servername,&serveraddr.sin_addr); - user2725511
1
请在您的问题中更新代码(不要在评论中发布更新后的代码,这很难阅读 :)) - nouney
2
向您的代码中添加一些错误检查,并阅读关于“gethostbyname(“localhost”)”的此问题 - nouney
2
@user2725511: "但仍然没有成功" 那么当前的错误是什么?你在哪里?有什么问题? - alk
显示剩余8条评论

4
检查端口。服务器端口为7400,但客户端尝试使用端口号11378连接,因此连接被拒绝。

1
请确保在您的程序中包含errno.h。
在任何失败之后,在您的程序中添加printf(“%s”,strerr(errno));行。 任何系统调用失败都会设置正确的errno,使诊断问题变得简单。

0

好的,你必须确保你的服务器正在运行并监听正确的端口(7400)。只需使用“netstat -tanp”检查是否有进程在端口7400上监听,然后尝试连接。


1
尽管在观察到连接问题时,这一步是常见的调试步骤之一,但根据OP的来源,本案例中问题在客户端。 - alk
更重要的是,服务器并没有在端口11378上运行。这是客户端还是服务器错误有争议。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接