Windows Socket UDP协议(服务器与客户端)

服务器普通实现代码

#include    
  
#pragma comment(lib,"Ws2_32.lib")//连接Sockets相关库  
  
void main()  
{  
    SOCKET socket1;  
    WSADATA wsaData;  
    if (WSAStartup(MAKEWORD(2, 1), &wsaData)) //初始化  
    {  
        printf("Winsock无法初始化!\n");  
        WSACleanup();  
        return;  
    }  
    printf("服务器开始创建SOCKET。\n");  
    struct sockaddr_in local;//本机地址相关结构体  
    struct sockaddr_in from;//客户端地址相关结构体  
    int fromlen = sizeof(from);  
    local.sin_family = AF_INET;  
    local.sin_port = htons(27015); ///监听端口   
    local.sin_addr.s_addr = INADDR_ANY; ///本机   
    socket1 = socket(AF_INET, SOCK_DGRAM, 0);  
    bind(socket1, (struct sockaddr*)&local, sizeof(local));//绑定SOCKET,此步关键  
    char buffer[1024] = "\0";  
    if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, &fromlen) != SOCKET_ERROR)//阻塞接受客户端的请求  
    {  
        printf("连接成功,开始发送数据\n");  
    }  
    while (1)  
    {  
        sendto(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, fromlen);//发数据给客户端,由于是  
        Sleep(200);  
    }  
    closesocket(socket1);  
    WSACleanup();  
}

客户端普通实现代码

#include    
#include    
  
#pragma comment(lib,"Ws2_32.lib")//连接Sockets相关库  
  
void main()  
{  
    SOCKET socket1;  
    WSADATA wsaData;  
    if (WSAStartup(MAKEWORD(2, 1), &wsaData)) //初始化  
    {  
        printf("Winsock无法初始化!\n");  
        WSACleanup();  
        return;  
    }  
    printf("客户端开始创建SOCKET。\n");  
    struct sockaddr_in server;  
    int len = sizeof(server);  
    server.sin_family = AF_INET;  
    server.sin_port = htons(27015); ///server的监听端口   
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); ///server的地址   
    socket1 = socket(AF_INET, SOCK_DGRAM, 0);  
    char buffer[1024] = "haha\0";  
    if (sendto(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, len) != SOCKET_ERROR)//发送信息给服务器,发送完进入等待,代表服务器在客户端启动前必须是等待状态  
    {  
        printf("发送请求,等待客户端接受并发送数据\n");  
    }  
    while (1)  
    {  
        Sleep(100);  
        if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, &len) != SOCKET_ERROR)  
        printf("从客户端接收到的数据:%s\n", buffer);  
    }  
    closesocket(socket1);  
    WSACleanup();  
  
}

在程序设计中通常希望对于数据交互方有没有数据传来做出反应,而不是单纯的阻塞等待在那里。这个时候可以用select先进行探测,一探测到有数据过来才调用recvfrom,如果超过时间则做出相应的超时处理,实现需要在上面的代码中recvfrom(原程序该函数阻塞)处稍作修改,修改代码如下:

fd_set readfds;  
FD_ZERO(&readfds);//将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的  
FD_SET(socket1, &readfds); //用于在文件描述符集合中增加一个新的文件描述符。  
struct timeval tv_out;  
tv_out.tv_sec = 5;//等待5秒  
tv_out.tv_usec = 0;  
int selright=select(socket1 + 1, &readfds, NULL, NULL, &tv_out);  
if (selright<=0)//为0时为超时,小于0时为错误,这两种情况皆非我们所想,故做出相同的处理  
{  
    printf("连接失败");  
    return;  
}  
else  
{  
    if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, &fromlen) != SOCKET_ERROR)//阻塞接受客户端的请求  
    {  
        printf("连接成功,开始发送数据\n");  
    }  
}  

 

你可能感兴趣的:(C++)