UDP协议
有别人总结好的,点这个
UDP与TCP的区别
也有别人总结好的,点这个
Socket编程
基本流程
头文件
#include<winsock2.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996) //避免由于版本库淘汰出现这个错误
server建立套接字、地址绑定
//定义服务端套接字,接受请求套接字
SOCKET s_server;
//服务端地址客户端地址
SOCKADDR_IN server_addr;
SOCKADDR_IN accept_addr;
//打开
WORD w_req = MAKEWORD(2, 2);//版本号
WSADATA wsadata;//结构体:拿到版本,版本校验
int err;
err = WSAStartup(w_req, &wsadata);//查看是否打开成功
if (err != 0)
{
cout << "打开失败!" << endl;
return 0;
}
else {
cout << "打开成功!" << endl;
}
//创建套接字
s_server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s_server == INVALID_SOCKET)
{
cout << "套接字设置失败" << endl;
return 0;
}
//填充服务端信息
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(7777);
if (bind(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
cout << "bind失败!" << endl;
WSACleanup();
return 0;
}
else {
cout << "bind成功!" << endl;
}
Client创建套接字
SOCKET c_client;
//服务端地址客户端地址
SOCKADDR_IN server_addr;
SOCKADDR_IN client_addr;
//定义主机名
char localhostname[256];
//打开
WORD w_req = MAKEWORD(2, 2);//版本号
WSADATA wsadata;
int err;
err = WSAStartup(w_req, &wsadata);//查看是否打开成功
if (err != 0)
{
cout << "打开失败!" << endl;
}
else {
cout << "打开成功!" << endl;
}
//绑定地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(7777);//转换为小端存储
//创建套接字
c_client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//创建客户端用于通信的Socket
//设置缓冲区及缓冲长度
int recv_len = 0;
int send_len = 0;
char recv_buf[100];
char send_buf[100];
int len = sizeof(client_addr);
发送数据
sendto(c_client, send_buf, strlen(send_buf), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
接收数据
recvfrom(c_client, recv_buf, strlen(recv_buf), 0, (SOCKADDR*)&client_addr, &len);
完整通讯过程
由于UDP协议没有监听连接等待过程,所以使用循环来实现两端通讯
//设置缓冲区及缓冲长度
int recv_len = 0;
int send_len = 0;
char recv_buf[100];
char send_buf[100];
int fromlen = sizeof(SOCKADDR);
while (1)
{
int len = recvfrom(s_server, recv_buf, 1024, 0, (SOCKADDR*)&accept_addr, &fromlen);
//cout << "11" << endl;
if (len > 0) { //判断接收到的数据是否为空
recv_buf[len] = '\0';//给字符数组加一个'\0',表示结束了。不然输出有乱码
if (strcmp(recv_buf, "bye") == 0) {
cout << "结束通话" << endl;
break;
}
else {
cout << recv_buf << endl;
}
}
cout << "回复客户端消息:";
cin >> send_buf; //给客户端回复消息
sendto(s_server, send_buf, strlen(send_buf), 0, (SOCKADDR*)&accept_addr, sizeof(SOCKADDR));
if (strcmp(send_buf, "bye") == 0) {
cout << "结束通讯" << endl;//当服务器发来bye时,关闭socket
break;
}
}
关闭套接字、释放内存
closesocket(s_server);
WSACleanup();