【问题标题】:Trouble with running Server-Client c program on Mac OS X Mountain Lion在 Mac OS X Mountain Lion 上运行 Server-Client c 程序时遇到问题
【发布时间】:2013-01-04 17:17:54
【问题描述】:

刚开始用c学习UNIX网络编程,做了一个TCP Server-Client的小程序。

它在 Fedora 上运行完美,但在我的 MacBook 上出现了一些连接问题。

编译可以在终端完成没有问题,但是在我运行“服务器”程序然后运行“客户端”程序后,似乎“服务器”没有从“客户端”获得“连接”命令.代码和消息如下:

server.c:

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

#define MYPORT 1500
#define BACKLOG 5
#define MAXDATASIZE 100

int main()
{
    int servSock, cliProc;
    socklen_t sin_size;
    char buf[MAXDATASIZE], msg[MAXDATASIZE];
    struct sockaddr_in my_addr, income_addr;

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MYPORT);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if ((servSock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        printf("Socket Error: %d\n", errno);
    else
        printf("Server Socket %d created\n", servSock);

    if (bind(servSock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
        printf("Bind Error: %d\n", errno);
    else
        printf("Server Bind created\n");

    listen(servSock, BACKLOG);
    printf("Server is waitting for connection...\n");

    sin_size = sizeof(struct sockaddr_in);
    if ((cliProc = accept(servSock, (struct sockaddr *)&income_addr, &sin_size)) == -1)
        printf("Accept Error: %d\n", errno);
    else
    {
        printf("Server accepted connection from %s\n", inet_ntoa(income_addr.sin_addr));
    }

    sprintf(msg, "Welcome to Server, you addr is %s", inet_ntoa(income_addr.sin_addr));
    send(cliProc, msg, strlen(msg), 0);

    if (recv(cliProc, buf, MAXDATASIZE, 0) == -1)
    {
        printf("Recv Error: %d\n", errno);
    }
    else
    {
        printf("Server received %s from %s\n", buf, inet_ntoa(income_addr.sin_addr));
    }

    close(cliProc);
    close(servSock);
    printf("Server Sockets closed\n");

    return 0;
}

client.c:

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

#define MAXDATASIZE 100
#define PORT 1500

int main(int argc, char *argv[])
{
    int cliSock, numbytes;
    char buf[MAXDATASIZE], msg[MAXDATASIZE];

    if (argc != 2)
    {
        printf("%d, Usage: Client Hostname\n", argc);
        exit(1);
    }

    struct hostent *he;

    if ((he = gethostbyname(argv[1])) == NULL)
    {
        printf("Couldn't get hostname\n");
        exit(1);
    }

    struct sockaddr_in dest_addr;

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    dest_addr.sin_addr = *((struct in_addr *)he->h_addr);

    if ((cliSock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        printf("Socket Error: %d\n", errno);
    else
        printf("Client Socket %d created\n", cliSock);

    if (connect(cliSock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) == 1)
        printf("Connect Error: %d\n", errno);
    else
    {
        printf("Client Connection created\n");
    }

    numbytes = recv(cliSock, buf, MAXDATASIZE, 0);
    buf[numbytes] = '\0';
    printf("Received Message: %s\n", buf);

    sprintf(msg, "4 8 15 16 23 42");
    send(cliSock, msg, MAXDATASIZE, 0);
    printf("Client sent %s to %s\n", msg, inet_ntoa(dest_addr.sin_addr));

    close(cliSock);
    printf("Client Sockets closed\n");

    return 0;
}

服务器消息:

Server Socket 3 created
Server Bind created
Server is waitting for connection...

客户端消息:

Client Socket 3 created
Client Connection created
Received Message:

任何帮助将不胜感激。 :)

【问题讨论】:

  • 尝试暂时关闭防火墙

标签: c macos sockets unix


【解决方案1】:

a) 在您的服务器上,添加验证以检查 listen 是否成功。它很可能会失败。您可以通过以下方式找出原因:

fprintf(stderr, "Error: %s\n", strerror(errno));

b) 在您的客户端上,以下条件正在检查错误的值。它应该检查!= 0。引用connectIf the connection or binding succeeds, zero is returned. On error, -1 is returned, and errno is set appropriately.

if (connect(cliSock,(struct sockaddr *)&dest_addr,sizeof(struct sockaddr)) == 1)
    printf("Connect Error: %d\n", errno);
else
    printf("Client Connection created\n");

c) 在像您这样的情况下,我通常建议使用已知有效的客户端测试连接,例如telnetnetcat。这有助于减少验证区域。如果连接不成功,则问题出在您的服务器上。否则,这是您的客户的问题。当然,你仍然可能在这两个方面都有问题,但你需要一次修复一个错误。

【讨论】:

  • 您好,感谢您的帮助,我确实在“connect()”检查了担忧值,在我更正了该部分后,它显示“errno”为 61,这意味着“客户端计算机无法连接到我试图连接到服务器上的 ip/端口”,所以我尝试直接连接到“127.0.0.1”,然后一切正常。所以真正的问题是关于 DNS 部分,结果“gethostbyname()”的结果是公共 IP 地址而不是本地 IP 地址。现在我想我将只使用本地 IP 地址进行测试。再次感谢,祝您有美好的一天! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
相关资源
最近更新 更多