C中的UDP套接字服务器/客户端?套接字不发送/接收数据

时间:2017-06-01 00:02:45

标签: c sockets networking udp datagram

无法让我的客户端将数据发送到服务器,或者我的服务器从客户端接收数据。任何我想到为什么也许?来到这里之前,我已经多次尝试重写代码,没有运气。 UDP套接字仍然是新手,遇到了麻烦。我是否使服务器/客户端功能正确?或者他们搞砸了,这就是为什么它不能正常工作?提前感谢您解决此问题的任何帮助。

/********************************************************************
 * svoip.c - Going to be a simple VOIP (Speak Over NET) application *
 ********************************************************************
 * By Philip R. Simonson                                            *
 ********************************************************************
 */

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <mmsystem.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <conio.h>

#define ALIAS "random_str"
#define MYPORT "31337"
#define MAXDATA 1024

typedef BOOL bool;

#define false FALSE
#define true TRUE

/* packet structs */
struct PACKET {
    char data[MAXDATA];
};
typedef struct PACKET packet_t;

struct FRAME {
    bool bArrived;
    packet_t packet;
};
typedef struct FRAME frame_t;

/* helper functions */
void clear_frame(frame_t *frame);
void *get_in_addr(struct sockaddr *sa);

/* setup functions */
int setup_server(void);
int setup_client(const char *hostname);

/* file functions */
int record_file(void);
int send_file(int sockfd, struct sockaddr_storage *client, const char *filename, frame_t *packet);
int recv_file(int sockfd, struct sockaddr_storage *server, const char *filename, frame_t *packet);
int play_file(const char *filename);

/* main() - entry point for application
 */
int main(int argc, char *argv[])
{
    WSADATA wsaData;
    int sockfd;
    struct sockaddr_storage client, addr;
    frame_t frame;

    if(argc > 2) {
        fprintf(stderr, "Usage: %s [address]\n", argv[0]);
        return 0;
    }

    memset(&client, 0, sizeof(client));
    memset(&addr, 0, sizeof(addr));
    clear_frame(&frame);

    WSAStartup(0x0202, &wsaData);
    if(argc == 1) {
        sockfd = setup_server();
        if(recv_file(sockfd, &client, "test.wav", &frame))
            goto error;
        printf("IP   : %s\nPORT : %s\n", inet_ntoa(((struct sockaddr_in *)&client)->sin_addr), MYPORT);
        if(play_file("tmp.wav"))
            goto error;
        if(remove("tmp.wav"))
            goto error;
    } else {
        sockfd = setup_client(argv[1]);
        puts("Press any key to record message...");
        getch();
        if(record_file() != 0)
            goto error;
        printf("IP   : %s\nPORT : %s\n", inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr), MYPORT);
        if(send_file(sockfd, &addr, "tmp.wav", &frame) != 0)
            goto error;
        if(remove("tmp.wav") != 0)
            goto error;
    }
    if(sockfd != 0)
        closesocket(sockfd);
    WSACleanup();
    return 0;

error:
    if(sockfd != 0)
        closesocket(sockfd);
    WSACleanup();
    return 1;
}

void clear_frame(frame_t *frame)
{
    frame_t ftmp;
    memset(&ftmp, 0, sizeof(ftmp));
/*  memset(&ftmp.packet, 0, sizeof(ftmp.packet)); */
}

void *get_in_addr(struct sockaddr *sa)
{
    if(sa->sa_family == AF_INET)
        return &(((struct sockaddr_in*)sa)->sin_addr);
    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int setup_server(void)
{
    struct addrinfo hints, *servinfo, *p;
    int sockfd;
    int rv;

    printf("*****************************\n"
        "* Tiny VOIP Application     *\n"
        "* By 5n4k3                  *\n"
        "*****************************\n\n");

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;

    if((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    /* loop through all the results and bind to the first it can */
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if((sockfd = socket(p->ai_family, p->ai_socktype,
            p->ai_protocol)) == -1) {
            perror("listener: socket()");
            continue;
        }

        if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("listener: bind()");
            continue;
        }

        break;
    }
    if(p == NULL) {
        fprintf(stderr, "listener: failed to bind socket\n");
        return 2;
    }
    freeaddrinfo(servinfo);
    printf("listener: waiting to recvfrom...\n");
    return sockfd;
}

int setup_client(const char *hostname)
{
    struct addrinfo hints, *servinfo, *p;
    int sockfd;
    int rv;

    printf("*****************************\n"
        "* Tiny VOIP Application     *\n"
        "* By 5n4k3                  *\n"
        "*****************************\n\n");

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    if((rv = getaddrinfo(hostname, MYPORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    /* loop through all the results and make a socket */
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if((sockfd = socket(p->ai_family, p->ai_socktype,
            p->ai_protocol)) == -1) {
            perror("talker: socket()");
            continue;
        }
        if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("client: connect()");
            continue;
        }
        break;
    }
    if(p == NULL) {
        fprintf(stderr, "talker: failed to create socket.\n");
        return 2;
    }
    freeaddrinfo(servinfo);
    puts("client: socket created.");
    return sockfd;
}

int record_file(void)
{
    char mci_command[100];
    char retstr[300];
    int mci_error;

    /* open wav type alias */
    sprintf(mci_command, "open new type waveaudio alias %s", ALIAS);
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);

    /* set the time format */
    sprintf(mci_command, "set %s time format ms", ALIAS);
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);

    sprintf(mci_command, "record %s notify", ALIAS);
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);

    printf("Now on air, press a key to stop.\n");
    getch();

    sprintf(mci_command, "stop %s", ALIAS);
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);

    sprintf(mci_command, "save %s %s", ALIAS, "tmp.wav");
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);

    sprintf(mci_command, "close %s", ALIAS);
    mci_error = mciSendString(mci_command, retstr, sizeof(retstr), NULL);
    printf("Recording stopped.\nPress a key to quit.\n");
    getch();
    return mci_error;
}

int send_file(int sockfd, struct sockaddr_storage *client, const char *filename, frame_t *frame)
{
    FILE *file;
    char *buf;
    char cwd[256];
    int client_len;
    int total_bytes;
    int bytes;

    if(getcwd(cwd, sizeof(cwd)) == NULL) {
        fprintf(stderr, "Error: Cannot get current working directory.\n");
        return -2;
    }
    strncat(cwd, "\\", sizeof(cwd));
    strncat(cwd, filename, sizeof(cwd));
    if((file = fopen(cwd, "rb")) == NULL) {
        fprintf(stderr, "Error: Cannot read input file.\n");
        close(sockfd);
        WSACleanup();
        exit(1);
    }

    bytes = 0;
    total_bytes = 0;
    frame->bArrived = false;
    while(frame->bArrived == 0) {
        bytes = fread(frame->packet.data, 1, MAXDATA, file);
        if(bytes > 0) {
            total_bytes += bytes;
            if(bytes == MAXDATA) {
                frame->bArrived = true;
            }
        }
        if(bytes == 0)
            break;
    }
    buf = malloc(sizeof(frame_t));
    if(!buf) {
        fprintf(stderr, "Out of memory.\n");
        fclose(file);
        close(sockfd);
        WSACleanup();
        exit(1);
    }
    memcpy(buf, frame, sizeof(frame_t));
    client_len = sizeof(struct sockaddr_storage);
    if(sendto(sockfd, buf, sizeof(frame_t), 0, (struct sockaddr *)client, client_len) == -1) {
        fprintf(stderr, "Couldn't send all of the data.\n");
    } else {
        printf("Sent %d bytes of data.\n", total_bytes);
    }
    free(buf);
    fclose(file);
    return 0;
}

int recv_file(int sockfd, struct sockaddr_storage *server, const char *filename, frame_t *frame)
{
    struct sockaddr_in addr;
    FILE *file;
    char cwd[256];
    int addrlen;
    int total_bytes;
    int bytes;

    if(getcwd(cwd, sizeof(cwd)) == NULL) {
        fprintf(stderr, "Error: Cannot get current working directory.\n");
        return -2;
    }
    strncat(cwd, "\\", sizeof(cwd));
    strncat(cwd, filename, sizeof(cwd));
    if((file = fopen(cwd, "wb")) == NULL) {
        fprintf(stderr, "Error: Cannot open file for writing.\n");
        return -1;
    }
    bytes = 0;
    total_bytes = 0;
    addr = *((struct sockaddr_in *)server);
    addrlen = sizeof(addr);
    while((bytes = recvfrom(sockfd, frame->packet.data, MAXDATA, 0, (struct sockaddr*)&addr,
        &addrlen)) != 0) {
        if(fwrite(frame->packet.data, 1, bytes, file) == -1) {
            fprintf(stderr, "Couldn't write all of the data.\n");
            break;
        }
        total_bytes += bytes;
    }
    fclose(file);
    if(bytes == 0) {
        printf("Received %d bytes of data.\n", total_bytes);
        frame->bArrived = 1;
    }

    return 0;
}

int play_file(const char *filename)
{
    if(PlaySound(filename, NULL, SND_FILENAME))
        return 1;
    return 0;
}

0 个答案:

没有答案