(一)UDPSocket 服务端编写(超详细)

效果演示在下一文中(客户端编写)


文章目录

  • TCP、UDP的区别
  • 服务端API介绍
  • 服务端源码(超详细)

TCP、UDP的区别

(一)UDPSocket 服务端编写(超详细)_第1张图片

UDP是面向无连接,也就是说当实现一个服务端对应多个客户端,不需要向TCPSocket那样使用多线程技术
UDP可以同时多个客户端对服务端传输数据


服务端API介绍

(一)UDPSocket 服务端编写(超详细)_第2张图片

  • SOCK_DGRAM:使用数据报套接字
  • bind:绑定地址(ip、端口)
  • sendto/recvfrom:发送数据 / 接收数据
  • close:释放套接字

服务端编写思路顺序与上面api顺序相同
UDPSocket 是不需要监听和接收的,绑定后直接收发数据


服务端源码(超详细)

老样子,代码我都会加以详细的注释(不用感谢,亲~)

#pragma comment(lib, "ws2_32.lib")	// 需要包含的链接库

#include 
#include 
#include 	// 2.2版本

void main(void)
{
    WSADATA		wsaData;		// 用于初始启动信息(初始化套接字)
    SOCKET		ReceivingSocket;	// 服务端的套接字
    SOCKADDR_IN		ReceiverAddr;		// 服务端的地址
    SOCKADDR_IN		SenderAddr;		// 客户端的地址
    int			SenderAddSize = sizeof(SOCKADDR);	// 保存地址大小 
    int			Ret;			// 用于判断 
    int			Port = 5150;		// 端口号(自定义)

    SenderAddrSize = sizeof(SOCKADDR);		// 赋值(地址大小)

    // 初始化套接字(版本号等),并判断是否成功
    if((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
    {
        printf("Error: WSAStartup failed with error %d\n", Ret);
        return;
    }
    else	// 初始化成功之后,判断是不是我们需要的 2.2 版本
    {
        // 判断低位和高位是不是都是 2
        if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
        {
            printf("Error: not winsock 2.2\n");	
            WSACleanup();	// 清空启动信息
            return;
        }
    }

    // 创建套接字
    if((ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
    {
        printf("Error: socket failed with error %d\n", WSAGetLastError());
        WSACleanup();
  	return;
    }

    // 初始化地址信息
    ReceiverAddr.sin_family = AF_INET;
    ReceiverAddr.sin_port = htons(Port);  // 转换成网络字节
    ReceiverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  // 本机的所有ip,都可以连接

    if(bind(ReceivingSocket, (SOCKADDR*)&ReceiverAddr, sizeof(ReceiverAddr)) == SOCKET_ERROR)
    {
        printf("Error: bind failed with error %d\n", WSAGetLastError());
  	closesocket(ReceivingSocket);
  	WSACleanup();
    	return;
    }
    
    // 开始收发数据
    while(1)
    {
        char buffer[1024] = '\0';	// 接受数据发送数据需要的数组
        printf("waiting for message from others ... \n");

        // 接收数据
        if((Ret = recvfrom(ReceivingSocket, buffer, sizeof(buffer), 0,
            (SOCKADDR*)&SenderAddr, &SenderAddrSize)) == SOCKET_ERROR)
        {
            printf("Error: recvfrom failed with error %d\n", WSAGetLastError());
  	    closesocket(ReceivingSocket);
  	    WSACleanup();
  	    return;
        }
        else	// 我们将接收到的数据,发送客户端
        {
            printf("Received datagram from %s -- %s\n", inet_ntoa(SenderAddr.sin_addr), buffer);
            
            // 发送数据
            sendto(ReceivingSocket, buffer, sizeof(buffer), 0, (SOCKADDR*)&SenderAddr, SenderAddrSize);
        }
        
    	Sleep(500);	// 有个缓冲的时间
    }

    closesocket(ReceivingSocket);	// 释放套接字
    WSACleanup();			// 清空启动信息

    system("pause");
}

客户端链接:

(二)UDPSocket 客户端编写(超详细)


  • 作者:浪子花梦
  • Time:2020.02.16
  • 三人行,必有我师

你可能感兴趣的:(网络编程)