C套接字编程通过同一连接发送多个发送和接收

派克·贝德纳(Parker Bednar)

我一直在尝试学习套接字编程,但是遇到了一些可能是白痴的问题。

我试图解决的问题是,为了注册客户端,从客户端向服务器发送了3个相同的发送。在这一点上,我有一个发送和接收工作,但不能使第二个或第三个工作。出于调试目的,我正在打印数据包结构的数据字段,在为第一个接收打印时,第二个接收为空白,第三个接收为一个奇特的蠕动框,后跟一个等号。我想我可能会陷入首次接收的困境,但是我真的不确定是什么问题。

在下面的代码中,我尝试发送相同的数据包3次,并且还尝试了下面的操作,发送3个不同的数据包,这些数据包都应包含相同的信息,结果始终是相同的。

这是客户端的代码:

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

#define SERVER_PORT 5654
#define MAX_LINE 256

/*structure of the packet*/
struct packet{
    short type;
    char data[MAX_LINE];
};

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

    struct packet packet_reg;
    struct packet packet_reg2;
    struct packet packet_reg3;
    struct hostent *hp;
    struct sockaddr_in sin;
    char *host;
    char buf[MAX_LINE];
    int s;
    int len;
    char hostname[1024];
    hostname[1023] = '\0';

    if(argc == 2){
        host = argv[1];
    }
    else{
        fprintf(stderr, "usage:newclient server\n");
        exit(1);
    }

    /* translate host name into peer's IP address */
    hp = gethostbyname(host);
    if(!hp){
        fprintf(stderr, "unkown host: %s\n", host);
        exit(1);
    }

    /* active open */
    if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0){
        perror("tcpclient: socket");
        exit(1);
    }

    /* build address data structure */
    bzero((char*)&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
    sin.sin_port = htons(SERVER_PORT);


    if(connect(s,(struct sockaddr *)&sin, sizeof(sin)) < 0){
        perror("tcpclient: connect");
        close(s);
        exit(1);
    }
    /* main loop: get and send lines of text */
    while(fgets(buf, sizeof(buf), stdin)){

        gethostname(hostname, 1023);
        printf("Hostname: %s\n", hostname);

        packet_reg.type = htons(121);
        strcpy(packet_reg.data,hostname);

        /*send the registration packet to the server*/
        if(send(s,&packet_reg,sizeof(packet_reg),0)<0){
            printf("\nsend failed\n");
            exit(1);
        }

        packet_reg2.type = htons(121);
        strcpy(packet_reg2.data,hostname);

        printf("%s\n",packet_reg2.data );

        /*send the registration packet to the server*/
        if(send(s,&packet_reg2,sizeof(packet_reg2),0)<0){
            printf("\nsend failed\n");
            exit(1);
        }

        packet_reg3.type = htons(121);
        strcpy(packet_reg3.data,hostname);

        /*send the registration packet to the server*/
        if(send(s,&packet_reg3,sizeof(packet_reg3),0)<0){
            printf("\nsend failed\n");
            exit(1);
        }

    }
}

这是服务器的代码,我通过尝试打印相同的数据包并替换其中的信息以及使用3个不同的数据包来完成了同样的事情。

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>

#define SERVER_PORT 5654
#define MAX_LINE 256
#define MAX_PENDING 5

/*structure of the packet*/
struct packet{
    short type;
    char data[50];
};

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

    struct packet packet_reg;
    struct packet packet_reg2;
    struct packet packet_reg3;
    struct sockaddr_in sin;
    struct sockaddr_in clientAddr;
    char buf[MAX_LINE];
    int s, new_s;
    int len;




    /* setup passive open */
    if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0){
        perror("tcpserver: socket");
        exit(1);
    }


    /* build address data structure */
    bzero((char*)&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(SERVER_PORT);


    if(bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0){
        perror("tcpclient: bind");
        exit(1);
    }
    listen(s, MAX_PENDING);

    /* wait for connection, then receive and print text */
    while(1){
        if((new_s = accept(s, (struct sockaddr *)&clientAddr, &len)) < 0){
            perror("tcpserver: accept");
            exit(1);
        }

        printf("\n Client's port is %d \n", ntohs(clientAddr.sin_port)); 


        if(recv(new_s,&packet_reg,sizeof(packet_reg),0)<0){
            printf("\ncouldnt receive first reg packet\n");
            exit(1);
        }
        printf("%s\n",packet_reg.data );


        if(recv(new_s,&packet_reg2,sizeof(packet_reg2),0)<0){
            printf("\not recieved second reg packet\n");

            exit(1);
        }
        printf("%s\n",packet_reg2.data );


        if(recv(new_s,&packet_reg3,sizeof(packet_reg3),0)<0){
            printf("\ncouldnt receive first reg packet\n");
            exit(1);
        }
        printf("%s\n",packet_reg3.data );



    }
}

任何帮助,将不胜感激。我确信这是一个愚蠢的错误,我只是不了解它是如何工作的。第一次使用c。

克里斯·多德(Chris Dodd)

因此,您会感到困惑的是,您没有数据包套接字-您正在使用的数据包套接字SOCK_STREAM使您可以传输字节流而不是packet每个sendrecv呼叫可以发送或接收的字节的任何量,并且必然有没有尺寸之间的任何连接-在多个字节发送发送可能在一个单一的recv被一起接收或字节在单个发送在多张接收可能被分裂。

这立即导致您的主要问题-您的客户端正在发送258字节的“数据包”,而服务器正在读取52字节的“数据包”。因此,您的第一个recv字节最多获取第一个字节的52个字节,send第二recv个字节从第一个字节的中间获取以下字节send(可能是随机未初始化的垃圾)。可能recv所有调用都返回完整的52个字节,但不能保证。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在同一连接中向TCP服务器发送多个消息

来自分类Dev

Spring Integration - 如何通过同一连接实现异步 TCP 套接字请求/响应?

来自分类Dev

C#-FtpWebRequest-通过同一连接/登录的多个请求

来自分类Dev

C#-FtpWebRequest-通过同一连接/登录的多个请求

来自分类Dev

c-udp在同一套接字上发送和接收

来自分类Dev

c-udp在同一套接字上发送和接收

来自分类Dev

由同一连接发送的查询是否并行执行?

来自分类Dev

通过同一连接(通过单个通道)访问多个gRPC服务

来自分类Dev

从同一套接字发送和接收数据的简单UDP示例

来自分类Dev

通过PHP套接字发送和接收多个JSON文字

来自分类Dev

在C中发送和接收结构-套接字编程

来自分类Dev

通过套接字在同一活动中发送和接收数据

来自分类Dev

通过套接字在同一活动中发送和接收数据

来自分类Dev

我是否可以通过同一UDP套接字同时发送和接收数据

来自分类Dev

在C#中的同一套接字上发送+接收数据

来自分类Dev

通过套接字发送和接收图像

来自分类Dev

可以在Twisted TCP的同一连接内发送两个单独的数据吗?

来自分类Dev

通过套接字连接发送多个请求

来自分类Dev

使用同一套接字发送和接收UDP多播数据包

来自分类Dev

通过套接字和端口发送和接收数据

来自分类Dev

使用EventMachine使用同一连接发出多个请求?

来自分类Dev

如何在同一端口上同时使用套接字发送和接收

来自分类Dev

同时在同一个套接字上发送和接收

来自分类Dev

套接字编程使用C语言中的循环发送和接收消息

来自分类Dev

在Activemq的同一连接中创建使用者和临时队列?

来自分类Dev

Java通过套接字发送和接收文件

来自分类Dev

通过套接字发送和接收照片错误

来自分类Dev

C#-同一连接实例上的TSQL并行事务

来自分类Dev

使用 C# 通过套接字发送和接收图像 | 使用 C# 共享屏幕

Related 相关文章

  1. 1

    在同一连接中向TCP服务器发送多个消息

  2. 2

    Spring Integration - 如何通过同一连接实现异步 TCP 套接字请求/响应?

  3. 3

    C#-FtpWebRequest-通过同一连接/登录的多个请求

  4. 4

    C#-FtpWebRequest-通过同一连接/登录的多个请求

  5. 5

    c-udp在同一套接字上发送和接收

  6. 6

    c-udp在同一套接字上发送和接收

  7. 7

    由同一连接发送的查询是否并行执行?

  8. 8

    通过同一连接(通过单个通道)访问多个gRPC服务

  9. 9

    从同一套接字发送和接收数据的简单UDP示例

  10. 10

    通过PHP套接字发送和接收多个JSON文字

  11. 11

    在C中发送和接收结构-套接字编程

  12. 12

    通过套接字在同一活动中发送和接收数据

  13. 13

    通过套接字在同一活动中发送和接收数据

  14. 14

    我是否可以通过同一UDP套接字同时发送和接收数据

  15. 15

    在C#中的同一套接字上发送+接收数据

  16. 16

    通过套接字发送和接收图像

  17. 17

    可以在Twisted TCP的同一连接内发送两个单独的数据吗?

  18. 18

    通过套接字连接发送多个请求

  19. 19

    使用同一套接字发送和接收UDP多播数据包

  20. 20

    通过套接字和端口发送和接收数据

  21. 21

    使用EventMachine使用同一连接发出多个请求?

  22. 22

    如何在同一端口上同时使用套接字发送和接收

  23. 23

    同时在同一个套接字上发送和接收

  24. 24

    套接字编程使用C语言中的循环发送和接收消息

  25. 25

    在Activemq的同一连接中创建使用者和临时队列?

  26. 26

    Java通过套接字发送和接收文件

  27. 27

    通过套接字发送和接收照片错误

  28. 28

    C#-同一连接实例上的TSQL并行事务

  29. 29

    使用 C# 通过套接字发送和接收图像 | 使用 C# 共享屏幕

热门标签

归档