C套接字问题-随机客户端地址和端口号

埃克斯克斯

我要做一个非常简单的练习:创建一个套接字,当客户端连接到该套接字时,服务器将显示其信息(地址和端口号)。

我这样写:

客户端

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

int main(int argc, char *argv[])
{
    // check arguments
    if (argc != 3)
    {
        fprintf(stderr, "Erreur argument\n");
        exit(EXIT_FAILURE);
    }
    char *nom_machine = argv[1];
    int port = atoi(argv[2]);

    int sock;
    struct sockaddr_in addr;

    // création socket
    sock = socket(AF_INET, SOCK_STREAM, 0);

    // remplissage struct de l'adresse
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port); // code les octets dans l'ordre réseau
    inet_aton(nom_machine, &addr.sin_addr);

    // connnexion à 1.2.3.4:4242
    connect(sock, (struct sockaddr *)&addr, sizeof addr);

    // display informations
    fprintf (stderr,
            "---------\nAdresse: %s\nPort: %hd\n---------\n",
            inet_ntoa(addr.sin_addr),
            ntohs(addr.sin_port));


    // envoie message
    int n = 7;
    int r = write(sock, &n, sizeof(int));
    if (r != sizeof(int)) {
        fprintf(stderr, "Echec de l'envoi de n\n");
        exit(EXIT_FAILURE);
    }

    // arrêt
    close(sock);

    exit(EXIT_SUCCESS);
}

服务器

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

int main(int argc, char *argv[])
{   
    if (argc != 2)
    {
        fprintf(stderr, "Erreur argument\n");
        exit(EXIT_FAILURE);
    }
    int port = atoi(argv[1]);

    int sock;
    struct sockaddr_in addr;

    // création socket
    sock = socket(AF_INET, SOCK_STREAM, 0);

    // remplissage struct de l'adresse
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port); // code les octets dans l'ordre réseau
    addr.sin_addr.s_addr = INADDR_ANY;

    // création connnexion
    bind(sock, (struct sockaddr *)&addr, sizeof addr);

    // écoute
    listen(sock, 2);

    // attend une connexion entrante
    struct sockaddr_in client_addr;
    socklen_t size;
    int lect = accept(sock, (struct sockaddr *)&client_addr, &size); // (2) structure entring connection

    // display client informations
    fprintf (stderr,
            "---------\nAdresse: %s\nPort: %d\n---------\n",
            inet_ntoa(client_addr.sin_addr),
            ntohs(client_addr.sin_port));

    // lecture message
    int n;
    int r = read(lect, &n, sizeof(int));
    if (r <= 0) {
                fprintf(stderr, "Le serveur n'a pas recu le message\n");
                close(sock);
                exit(EXIT_FAILURE);
    }
    // Affichage
    fprintf(stderr, "%d\n", n);

    // arrêt
    close(sock);

    exit(EXIT_SUCCESS);
}

不幸的是,当我测试代码时,服务器提供的客户端地址和端口号似乎是完全随机的(除了有时它提供正确的地址,但我从未看到正确的端口号)。

这是一个例子:

控制台客户端

thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ gcc -g -Wall -Wextra -Og -o client client.c
thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ ./client 127.0.0.1 3333
---------
Adresse: 127.0.0.1
Port: 3333
---------
thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ ./client 127.0.0.1 3333
---------
Adresse: 127.0.0.1
Port: 3333
---------

服务器控制台

thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ gcc -g -Wall -Wextra -Og -o serveur serveur.c
thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ ./serveur 3333
---------
Adresse: 6.127.0.0
Port: 16578
---------
Le serveur n'a pas recu le message
thomas@thomasCoding:~/Code/2020/Reseau/TP_4$ ./serveur 3333
---------
Adresse: 127.0.0.1
Port: 55098
---------
7

如果有人可以帮我弄清楚我的错误。谢谢 :)

Ctx

您在手册accept(2)中缺少这一点

addrlen参数是一个值结果参数:调用者必须对其进行初始化,以包含addr指向的结构的大小(以字节为单位);返回时,它将包含对等地址的实际大小。

这意味着您必须要做

socklen_t size = sizeof client_addr;

否则,如果in中的值size(不确定)太小,返回的地址将被截断,这意味着内容可能未初始化(全部或部分)。这导致您观察到奇怪的值。

另一个问题是,当最近使用该端口(TIME_WAIT状态)时,该地址bind()可能会因已使用的地址而失败在这种情况下,端口会自动从某个实现定义的范围进行绑定。为了避免这种情况,您可以在以下选项SO_REUSEADDR之前设置选项bind()

int one = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));

此外,建议检查所有返回值是否有错误;您可能会注意到bind()失败了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用IP地址和端口号连接到服务器套接字?(客户端在与服务器不同的机器上运行)

来自分类Dev

C#多个客户端-发送昵称以及IP和端口号

来自分类Dev

C ++客户端/套接字问题

来自分类Dev

客户端套接字找不到服务器套接字。尽管具有相同的端口号,但引发UnknownHostException

来自分类Dev

如何在C套接字(sys / socket.h)中获得客户端的地址和端口?

来自分类Dev

Python套接字利用客户端地址和端口进行响应

来自分类Dev

端口号和套接字之间的区别

来自分类Dev

XAMPP和C#套接字IPAdress问题

来自分类Dev

使用不同的端口号创建套接字时已使用的地址

来自分类Dev

读取时的客户端套接字问题

来自分类Dev

套接字客户端问题“ __getitem__”

来自分类Dev

Java客户端/服务器套接字问题

来自分类Dev

将客户端套接字与服务器套接字连接时出现问题

来自分类Dev

如何在Node.js中检索客户端和服务器的IP地址和端口号

来自分类Dev

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

来自分类Dev

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

来自分类Dev

如何找到要连接到侦听套接字的客户端的源ip和端口?

来自分类Dev

套接字,传输类型,端口号,IP之间的关系

来自分类Dev

uwsgi --stats显示套接字的不同端口号

来自分类Dev

查找服务器套接字的端口号

来自分类Dev

如何从套接字中提取端口号?

来自分类Dev

有关在C(Linux)中的套接字服务器客户端编程中的accept()的问题

来自分类Dev

有关C语言(Linux)中套接字服务器客户端编程中accept()的问题

来自分类Dev

C套接字客户端发送换行符

来自分类Dev

C客户端/服务器套接字错误

来自分类Dev

C套接字客户端发送换行符

来自分类Dev

将输入从C套接字客户端读取到Java套接字服务器

来自分类Dev

无法从Java套接字服务器接收数据到C套接字客户端

来自分类Dev

将输入从C套接字客户端读取到Java套接字服务器

Related 相关文章

  1. 1

    如何使用IP地址和端口号连接到服务器套接字?(客户端在与服务器不同的机器上运行)

  2. 2

    C#多个客户端-发送昵称以及IP和端口号

  3. 3

    C ++客户端/套接字问题

  4. 4

    客户端套接字找不到服务器套接字。尽管具有相同的端口号,但引发UnknownHostException

  5. 5

    如何在C套接字(sys / socket.h)中获得客户端的地址和端口?

  6. 6

    Python套接字利用客户端地址和端口进行响应

  7. 7

    端口号和套接字之间的区别

  8. 8

    XAMPP和C#套接字IPAdress问题

  9. 9

    使用不同的端口号创建套接字时已使用的地址

  10. 10

    读取时的客户端套接字问题

  11. 11

    套接字客户端问题“ __getitem__”

  12. 12

    Java客户端/服务器套接字问题

  13. 13

    将客户端套接字与服务器套接字连接时出现问题

  14. 14

    如何在Node.js中检索客户端和服务器的IP地址和端口号

  15. 15

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

  16. 16

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

  17. 17

    如何找到要连接到侦听套接字的客户端的源ip和端口?

  18. 18

    套接字,传输类型,端口号,IP之间的关系

  19. 19

    uwsgi --stats显示套接字的不同端口号

  20. 20

    查找服务器套接字的端口号

  21. 21

    如何从套接字中提取端口号?

  22. 22

    有关在C(Linux)中的套接字服务器客户端编程中的accept()的问题

  23. 23

    有关C语言(Linux)中套接字服务器客户端编程中accept()的问题

  24. 24

    C套接字客户端发送换行符

  25. 25

    C客户端/服务器套接字错误

  26. 26

    C套接字客户端发送换行符

  27. 27

    将输入从C套接字客户端读取到Java套接字服务器

  28. 28

    无法从Java套接字服务器接收数据到C套接字客户端

  29. 29

    将输入从C套接字客户端读取到Java套接字服务器

热门标签

归档