简体   繁体   English

在同一个C程序中的两个线程之间发送UDP消息(Linux)

[英]Sending UDP messages between two threads in the same C program (Linux)

For a class my group has been assigned to write a program that has two thread, where one thread sends 20 UDP messages to the other thread. 对于一个类,我的小组已被分配编写一个具有两个线程的程序,其中一个线程向另一个线程发送20条UDP消息。 The IP address, port numbers, and rate at which the transmit thread sends messages is passed in as command line arguments. 传输线程发送消息的IP地址,端口号和速率作为命令行参数传入。 When we try to run the program we get the error "sendto failed: Bad Address". 当我们尝试运行程序时,出现错误“发送失败:错误的地址”。 We've been trying to figure out why, but we're stumped. 我们一直在试图找出原因,但我们感到困惑。 We think it has something to do with the recAddr struct. 我们认为这与recAddr结构有关。 Does anyone have any ideas? 有人有什么想法吗?

#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/time.h>

const int ipTx = 1, ipRx = 2, portTx = 3, portRx = 4, TxRate = 5;
const int wait_five = 5, num_msgs = 20, wait_ten = 10, wait_twenty = 20;
const int SEC_TO_MILLI = 1000;
int *message;

void *send_msg( void * );
void *receive_msg( void * );

int main( int argc, char *argv[] )
{
    message = 0;
    pthread_t sendThread, recieveThread;
    int sendFail, recFail;

    sendFail = pthread_create(&sendThread, NULL, send_msg, (void*) argv);
    if(sendFail)
    {
        printf("Error creating send thread\n");
    }

    recFail = pthread_create(&recieveThread, NULL, receive_msg, (void*) argv);
    if(recFail)
    {
        printf("Error creating receive thread\n");
    }

    pthread_join( sendThread, NULL);
    pthread_join( recieveThread, NULL);

    printf("Send thread and receive thread done. Program terminating.\n");

    return 0;
}

void *send_msg( void *argv)
{
    char **args = (char **)argv;
    int sendSocket;
    if((sendSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("cannot create send socket");
        return;
    }
    struct sockaddr_in myAddr;
    memset((char *)&myAddr, 0, sizeof(myAddr));
    myAddr.sin_family = AF_INET;
    myAddr.sin_addr.s_addr = inet_addr(args[ipTx]);
    int port = htons(atoi(args[portTx]));
    myAddr.sin_port = htons(port);
    if (bind(sendSocket, (struct sockaddr *)&myAddr, sizeof(myAddr)) < 0) 
    {
        perror("send socket bind failed");
        return;
    }

    struct sockaddr_in recAddr;
    memset((char*)&recAddr, 0, sizeof(recAddr));
    recAddr.sin_family = AF_INET; 
    recAddr.sin_port = htons(atoi(args[portRx]));
    recAddr.sin_addr.s_addr = inet_addr(args[ipRx]);

    printf("Sleeping for 5 seconds\n");
    sleep(wait_five);

    int sendRate = (intptr_t) args[TxRate];
    sendRate /= SEC_TO_MILLI;
    int i;
    for(i = 0; i < num_msgs; i++)
    {
        printf("I am TX and I am going to send a %i\n", message);
        if(sendto(sendSocket, message, sizeof(message), 0, (struct sockaddr *)&recAddr, sizeof(recAddr) ) < 0)
        {
            perror("sendto failed");
            return;
        }
        *message++;
        sleep(sendRate);
    }
    printf("Sleeping for 10 seconds\n");
    sleep(wait_ten);
}

void *receive_msg( void *argv)
{
    const int BUFF_SIZE = 2048;

    char **args = (char **)argv;

    struct sockaddr_in myAddress;
    struct sockaddr_in remoteAddress;
    socklen_t addressLength = sizeof(myAddress);
    int recvLength;
    int receiveSocket;
    unsigned int buf[BUFF_SIZE];

    if((receiveSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("cannot create receive socket\n");
        return;
    }

    memset((char*)&myAddress, 0, sizeof(myAddress));
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr(args[ipRx]);;
    myAddress.sin_port = htons(atoi(args[portRx]));

    struct timeval rec_timeout;
    rec_timeout.tv_sec = wait_twenty;
    rec_timeout.tv_usec = 0;

    if(setsockopt(receiveSocket, SOL_SOCKET, SO_RCVTIMEO, (const void *)&rec_timeout, sizeof(rec_timeout)) < 0)
    {
        perror("cannot set timeout option\n");
        return;
    }

    if(bind(receiveSocket, (const struct sockaddr *)&myAddress, sizeof(myAddress)) < 0)
    {
        perror("cannot bind receive socket\n");
        return;
    }

    for(;;)
    {
        printf("waiting on port %d\n", atoi(args[portRx]));
        recvLength = recvfrom(receiveSocket, buf, BUFF_SIZE, 0, (struct sockaddr*)&remoteAddress, &addressLength);
        printf("received %d bytes\n", recvLength);
        if (recvLength > 0)
        {
            buf[recvLength] = 0;
            printf("I am RX and I got a \"%d\"\n", buf);
        }
    }
}

Here's the code in script file we use: 这是我们使用的脚本文件中的代码:

#!/bin/bash
gcc -pthread -o prototype1.out prototype1.c
./prototype1.out 137.104.21.4 137.104.21.4 7084 7085 50

Thank you! 谢谢!

sendto(sendSocket, message, sizeof(message), 0, (struct sockaddr *)&recAddr, sizeof(recAddr) )

The problem here is that message is NULL. 这里的问题是message为NULL。

This pointer is 该指针是

1) Initialized to a NULL. 1)初始化为NULL。 The second argument to sendto() should point to valid memory at least the size given by the third argument. sendto()的第二个参数应至少指向第三个参数指定的有效内存。

2) The code assumes that this pointer is initialized to at least sizeof(message) bytes worth of memory. 2)代码假定此指针已初始化为至少sizeof(message)个字节的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM