如何从accept调用中获取套接字端口号(C UNIX)

时间:2014-09-15 13:10:55

标签: c sockets unix port

我已经完成了一个简单的客户端/服务器程序,其中服务器等待外部连接并返回连接套接字,如果客户端的端口号在[1025-2048]范围内,否则返回-1。问题是,当我通过客户端地址获取端口号(应该存储在sockaddr结构中)时,它告诉我客户端端口号为零,但在客户端程序中我设置了客户端portnumber到1999年。

服务器

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


int function(int fd_socket) {

    int fd_socket_acc;
    int len;
    int port;
    struct sockaddr_in client_addr;

    puts("WAITING FOR CLIENT...");

    fd_socket_acc = accept(fd_socket, (struct sockaddr*)&client_addr, &len);

    puts("CONNECTION DONE.");

    port = ntohs (client_addr.sin_port);
    printf("client port number: %d \n", port);


    if (port >= 1024 && port <= 2048) {

        close (fd_socket_acc);
        return fd_socket_acc;
    }   
    else {
        close(fd_socket_acc);
        return -1;
    }
}

int main(int argc, char *argv[]) {


    int fd_socket;
    struct sockaddr_in local_addr;

    fd_socket = socket(AF_INET, SOCK_STREAM, 0);

    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(1887);
    local_addr.sin_addr.s_addr = INADDR_ANY;

    bind(fd_socket, (struct sockaddr*)&local_addr, sizeof(local_addr));

    listen(fd_socket, 3);

    function(fd_socket);

    //close(fd_socket);

}

客户端

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

int main(int argc, char *argv[]) {

    int fd_socket;
    struct sockaddr_in local_addr;
    struct sockaddr_in server_addr;
    struct hostent *hp;

    fd_socket = socket(AF_INET, SOCK_STREAM, 0);

    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(1999);
    local_addr.sin_addr.s_addr = INADDR_ANY;

    bind(fd_socket, (struct sockaddr*)&local_addr, sizeof(local_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(1887);
    //hostname is "ubuntu"
    hp = gethostbyname("ubuntu");
    bcopy(hp->h_addr, &server_addr.sin_addr, 4);

    printf("%d \n", ntohs(local_addr.sin_port));

    connect(fd_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

    wait(2);

    close(fd_socket);

}

如果我在客户端使用printf("%d", ntohs(local_addr.sin_port))获取端口号,则会正确标记1999,但如果我在服务器中获得printf("%d", ntohs(client_addr.sin_port))的客户端端口号,则会标记{{1} }。为什么呢?

提前感谢!

2 个答案:

答案 0 :(得分:4)

要在client_addraccept中获取客户端端口号,您必须通过设置{/ 1}告诉accept缓冲区有多大

socklen_t len = sizeof(client_addr);

您也可以通过之后调用

来检索它
len = sizeof(client_addr);
getpeername(fd_socket_acc, (struct sockaddr*)&client_addr, &len);

答案 1 :(得分:1)

也许是因为你没有将变量len设置为任何东西,我怀疑你的编译器将它设置为0 你会尝试接受一个未定义的len大小。

在调用accept之前添加len=sizeof( struct sockaddr_in );将有助于正确填充传递的client_addr。