码迷,mamicode.com
首页 > Windows程序 > 详细

基于windows的回声udp服务器端/客户端

时间:2018-11-05 12:52:29      阅读:424      评论:0      收藏:0      [点我收藏+]

标签:puts   服务器   main   传递数据   code   class   tar   win   rcm   

udp是具有数据边界的协议,传输中调用I/O函数的次数非常重要。输入函数的调用次数要和输出函数的调用次数完全一致,这样才能保证接受全部已发送的数据。

tcp套接字中需注册待传输数据的目标IP和端口,而udp中无需注册。通过sendto函数传递数据的过程大约分为3个阶段:
第1阶段:向udp套接字注册目标IP和端口号。
第2阶段:传输数据。
第3阶段:删除udp套接字中注册的目标地址信息。
每次调用sendto函数时都会重复上述过程。这种未注册目标地址信息的套接字成为未连接套接字,反之,注册了目标地址的套接字称为连接套接字。udp默认属于未连接套接字,创建已连接udp套接字只需调用connect函数,这样可以提高效率。

 

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>

#define BUF_SIZE 64

void ErrorHandling(char* message);

int main()
{
    WSADATA wsa_data;
    SOCKET server_sock;
    SOCKADDR_IN server_addr, client_addr;
    int sz_client_addr;
    char message[BUF_SIZE];
    int str_len;

    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        ErrorHandling("WSAStartup() error.");

    server_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (server_sock == INVALID_SOCKET)
        ErrorHandling("socket() error.");

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(8000);

    if (bind(server_sock, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
        ErrorHandling("bind() error.");

    while (true)
    {
        sz_client_addr = sizeof(client_addr);
        str_len = recvfrom(server_sock, message, BUF_SIZE, 0, (SOCKADDR*)&client_addr, &sz_client_addr);
        sendto(server_sock, message, str_len, 0, (SOCKADDR*)&client_addr, sizeof(message));
    }
    closesocket(server_sock);
    WSACleanup();
    return 0;
}

void ErrorHandling(char* message)
{
    fputs(message, stderr);
    fputc(\n, stderr);
    exit(1);
}

 

使用连接套接字的客户端:

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>

#define BUF_SIZE 64

void ErrorHandling(char* message);

int main()
{
    WSADATA wsa_data;
    SOCKET h_socket;
    SOCKADDR_IN server_addr;

    char message[BUF_SIZE];
    int str_len;

    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        ErrorHandling("WSAStartup() error.");

    h_socket = socket(PF_INET, SOCK_DGRAM, 0);
    if (h_socket == INVALID_SOCKET)
        ErrorHandling("socket() error.");

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(8000);

    if (connect(h_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
        ErrorHandling("connect() error.");

    while (true)
    {
        fputs("Insert message(q to quit): ", stdout);
        fgets(message, sizeof(message), stdin);
        if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
            break;
        send(h_socket, message, strlen(message), 0);
        str_len = recv(h_socket, message, sizeof(message) - 1, 0);
        message[str_len] = 0;
        printf("Message from server: %s", message);
    }
    closesocket(h_socket);
    WSACleanup();
    return 0;
}

void ErrorHandling(char* message)
{
    fputs(message, stderr);
    fputc(\n, stderr);
    exit(1);
}

 

使用未连接套接字的客户端:

 

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>

#define BUF_SIZE 64

void ErrorHandling(char* message);

int main()
{
    WSADATA wsa_data;
    SOCKET h_socket;
    SOCKADDR_IN server_addr, from_addr;

    char message[BUF_SIZE];
    int str_len;

    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        ErrorHandling("WSAStartup() error.");

    h_socket = socket(PF_INET, SOCK_DGRAM, 0);
    if (h_socket == INVALID_SOCKET)
        ErrorHandling("socket() error.");

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(8000);

    while (true)
    {
        fputs("Insert message(q to quit): ", stdout);
        fgets(message, sizeof(message), stdin);
        if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
            break;
        sendto(h_socket, message, strlen(message), 0, (SOCKADDR*)&server_addr, sizeof(server_addr));
        int sz_from_addr = sizeof(from_addr);
        str_len = recvfrom(h_socket, message, BUF_SIZE, 0, (SOCKADDR*)&from_addr, &sz_from_addr);
        message[str_len] = 0;
        printf("Message from server: %s", message);
    }
    closesocket(h_socket);
    WSACleanup();
    return 0;
}

void ErrorHandling(char* message)
{
    fputs(message, stderr);
    fputc(\n, stderr);
    exit(1);
}

 

基于windows的回声udp服务器端/客户端

标签:puts   服务器   main   传递数据   code   class   tar   win   rcm   

原文地址:https://www.cnblogs.com/ACGame/p/9908215.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!