Connectionless is udp communication
Topology:
-------------------------------------------------------------------------------------------------------------
Server<---------------------------->Client
127.0.0.1:8888
-------------------------------------------------------------------------------------------------------------
Learn about the steps of udp socker
Server:
1. Create a datagram socket and return the socket number s【socket( )】
2. Bind the socket s to the local address (IP+port) [bind( )]
3. Read/write data on socket ns until the end [sendto( )] [recvfrom( )]
4. Close the socket ns [closesocket( )]
Client:
1. Create a datagram socket and return the socket number s【socket( )】
2. Read/write data on socket ns until the end [sendto( )] [recvfrom( )]
3. Close the socket ns [closesocket( )]
The client does not need to bind the address
-------------------------------------------------------------------------------------------------------------
Compiled by vs2017
If the compilation fails, you can replace the old function name.
Server:
// Udp_server.cpp: 定义控制台应用程序的入口点。
//
//相关头文件
#include "stdafx.h"
#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")
int main()
{
//初始化
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup initialization failed");
return 0;
}
//变量的声明,赋值
SOCKET RecvSocket;
sockaddr_in RecvAddr;
int Port = 8888;
char RecvBuf[1024]; //接收缓冲
char SendBuf[1024]; //发送缓冲
int BufLen = 1024;
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
//创建接受数据的socket
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//绑定ip和端口
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(RecvSocket, (SOCKADDR *)&RecvAddr, sizeof(RecvAddr));
printf("Server ready:\n");
while (true) {
//接收
int re_number = recvfrom(RecvSocket,
RecvBuf,
BufLen,
0,
(SOCKADDR *)&SenderAddr,
&SenderAddrSize
);
if (re_number > 0) {
printf("from client :%s\n", &RecvBuf);
if (strcmp(RecvBuf, "quit") == 0)
{
closesocket(RecvSocket);
return 0;
}
}
//发送
gets_s(SendBuf); //获取键盘输入
//发送函数
int send_number = sendto(RecvSocket,
SendBuf, BufLen,
0,
(SOCKADDR *)&SenderAddr,
sizeof(SenderAddr)
);
printf("server_to_client: %s\n", SendBuf);
if (strcmp(SendBuf, "quit") == 0){
closesocket(RecvSocket);
return 0;
}
}
if (WSACleanup() == SOCKET_ERROR)
printf("WSACleanup failed");
return 0;
}
Client
// Udp_Client.cpp: 定义控制台应用程序的入口点。
//
//相关头文件
#include "stdafx.h"
#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
#include <Ws2tcpip.h> //第35行函数需要此头文件
using namespace std;
#pragma comment(lib,"WS2_32.lib")
int main()
{
//初始化
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup initialization failed");
return 0;
}
//变量的声明,赋值
SOCKET SendSocket;
sockaddr_in RecvAddr; //服务器端的地址
int Port = 8888;
char SendBuf[1024];
char RecvBuf[1024];
int BufLen = 1024;
//创建soclket
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//设置服务器地址
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
//RecvAddr.sin_addr.s_addr = inet_addr("192.168.1.1"); //vs2017不支持此写法
InetPton(AF_INET, _T("127.0.0.1"), &RecvAddr.sin_addr.s_addr);
int RecvAddrSize = sizeof(RecvAddr);
//向服务器发送数据
printf("client ready:\n");
while (true) {
//scanf_s("%s",SendBuf); //如果使用这个函数,则会向客户端发送死循环的“烫”,原因不明
//发送
gets_s(SendBuf);
int st = sendto(SendSocket,
SendBuf,
BufLen,
0,
(SOCKADDR *)&RecvAddr,
sizeof(RecvAddr)
);
if (strcmp(SendBuf, "quit") == 0) {
closesocket(SendSocket);
return 0;
}
//接受
int recv_number = recvfrom(SendSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&RecvAddr, &RecvAddrSize);
printf("From server: %s\n" ,RecvBuf);
if (strcmp(RecvBuf, "quit") == 0) {
closesocket(SendSocket);
return 0;
}
if (st == SOCKET_ERROR) {
printf("send failed! \n");
closesocket(SendSocket);
WSACleanup();
return -1;
}
}
}
Experimental effect: