WinSocket编程笔记(五)

三.UDP的Socket编程

先前的socket服务器端与客户端需要建立连接才能通信,因此是面向连接的基于TCP的Socket。而这里的基于UDP的Socket是面向无连接的,也就是说不必调用 listen() 和 accept() 函数,那么connect()函数也就一样没有使用的必要了。

UDP新增的函数:

1.发送数据sendto() 函数(相比send()函数多了最后面两个参数)

函数原型:

 

int sendto(int s, const void * buf, int len, unsigned int flags, const struct sockaddr * to, int addrlen);

 

  • sock:用于传输UDP数据的套接字;
  • buf:保存待传输数据的缓冲区地址;
  • len:带传输数据的长度(以字节计);
  • flags:可选项参数,若没有可传递0;
  • to:存有目标地址信息的 sockaddr 结构体变量的地址;
  • addrlen:传递给参数 to 的地址值结构体变量的长度;

定义实例:

sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr));

2.接收数据recvfrom() 函数

 

函数原型:

 

int recvfrom(SOCKET sock, char *buf, int nbytes, int flags, const struct sockaddr *from, int *addrlen);

 

  • sock:用于接收UDP数据的套接字;
  • buf:保存接收数据的缓冲区地址;
  • nbytes:可接收的最大字节数(不能超过buf缓冲区的大小);
  • flags:可选项参数,若没有可传递0;
  • from:存有发送端地址信息的sockaddr结构体变量的地址;
  • addrlen:保存参数 from 的结构体变量长度的变量地址值;

定义实例:

recvfrom(sock, buffer, BUF_SIZE, 0, &clntAddr, &nSize);

 

基于UDP的Socket编程

服务器:

#include <cstdio>
#include<iostream>
#include<string>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
const int PORT = 8000;
#define BUF_SIZE 100

int main(){
WORD sockVersion = MAKEWORD(2, 2);

    WSADATA data;

    if (WSAStartup(sockVersion, &data) != 0)

    {

        return 1;

    }
SOCKET ListenSocket = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN ListenAddr;
ListenAddr.sin_family=AF_INET;
ListenAddr.sin_addr.S_un.S_addr=INADDR_ANY;
ListenAddr.sin_port=htons(PORT);
int n;
n=bind(ListenSocket,(LPSOCKADDR)&ListenAddr,sizeof(ListenAddr));
if(n==SOCKET_ERROR){
cout<<"端口绑定失败!"<<endl;
return -1;
}
else{
cout<<"端口绑定成功:"<<PORT<<endl;
}
//接收客户端
SOCKADDR clntAddr;  //客户端地址信息
int nSize = sizeof(SOCKADDR);
char buffer[BUF_SIZE];  //缓冲区
while(1){
    int strLen = recvfrom(ListenSocket, buffer, BUF_SIZE, 0, &clntAddr, &nSize);
    sendto(ListenSocket, buffer, strLen, 0, &clntAddr, nSize);
}
closesocket(ListenSocket);
 WSACleanup();
 return(0);
}

 

客户端:

#include <cstdio>
#include<iostream>
#include<string>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
const int PORT = 8001;
#define BUF_SIZE 100

int main(){
WORD sockVersion = MAKEWORD(2, 2);

    WSADATA data;

    if (WSAStartup(sockVersion, &data) != 0)

    {

        return 1;

    }
SOCKET ListenSocket = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN ListenAddr;
ListenAddr.sin_family=AF_INET;
ListenAddr.sin_addr.S_un.S_addr=INADDR_ANY;
ListenAddr.sin_port=htons(PORT);
int n;
n=bind(ListenSocket,(LPSOCKADDR)&ListenAddr,sizeof(ListenAddr));
if(n==SOCKET_ERROR){
cout<<"端口绑定失败!"<<endl;
return -1;
}
else{
cout<<"端口绑定成功:"<<PORT<<endl;
}
//服务器地址信息
    sockaddr_in servAddr;
    memset(&servAddr, 0, sizeof(servAddr));  //每个字节都用0填充,可省略
    servAddr.sin_family = PF_INET;
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servAddr.sin_port = htons(1234);
    //不断获取用户输入并发送给服务器,然后接受服务器数据
    sockaddr fromAddr;
    int addrLen = sizeof(fromAddr);
    while(1){
        char buffer[BUF_SIZE] = {0};
        printf("Input a string: ");
        gets(buffer);
        sendto(ListenSocket, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
        recvfrom(ListenSocket, buffer, BUF_SIZE, 0, &fromAddr, &addrLen);
        cout<<"Message from server:"<<buffer<<endl;
    }
closesocket(ListenSocket);
 WSACleanup();
 return(0);
}

服务器端接收到客户端信息以后发回给客户端,客户端打印接收到的消息

运行结果

 

 

(待续)

 

posted @ 2020-04-19 16:38  ch0bits  阅读(242)  评论(0编辑  收藏  举报