首页 > 代码库 > 23Socket实现UDP服务器端和客户端连接传输

23Socket实现UDP服务器端和客户端连接传输

客户端

23UdpClient.cpp
代码:
// 23UdpClient.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"


#include <stdio.h>
//Windows套接字所需的头文件
#include <WINSOCK.H>
//Windows套接字接口的库文件
#pragma comment(lib, "WSOCK32.LIB")


//程序使用的WinSock主版本
#define SOCK_VER 2
//变量和函数声明
SOCKET g_sock = 0;
void ErrMsg(DWORD dwErr);



int _tmain(int argc, _TCHAR* argv[])
{
	//初始化WinSock环境
	WSADATA wd = {0};
	int nStart = WSAStartup(MAKEWORD(SOCK_VER, 0), &wd);
	if(nStart = 0)
	{
		//初始化失败
		return 0;
	}
	//检测当前系统的WinSock版本是否支持所需版本
	if(LOBYTE(wd.wVersion) != 2)
	{
		return 0;
	}
	//创建一个UDP Socket
	g_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(g_sock == INVALID_SOCKET)
	{
		ErrMsg(WSAGetLastError());
		return 0;
	}
	printf("Socket创建成功\n");
	//发数据的目标地址
	sockaddr_in addr = {0};
	addr.sin_family = AF_INET;
	addr.sin_port = htons(2800);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//发出数据包
	char szBuff[] = "hello UDP!";
	int nSent = sendto(g_sock, szBuff, strlen(szBuff) + 1, 0, (sockaddr *)&addr, sizeof(addr));
	if(nSent == 0)
		ErrMsg(WSAGetLastError());
	else
		printf("信息成功发出,等待回应...\n");
	//等待回应
	sockaddr_in saServer = {0};
	int nFromLen = sizeof(saServer);
	*szBuff = '\0';
	int nRecv = recvfrom(g_sock, szBuff, 256, 0, (sockaddr *)&saServer, &nFromLen);
	if(SOCKET_ERROR == nRecv)
		ErrMsg(WSAGetLastError());
	else
		printf("收到回应:%s 从%s,%d\n", szBuff, inet_ntoa(saServer.sin_addr), ntohs(saServer.sin_port));
	//关闭套接字
	closesocket(g_sock);
	//等待用户输入
	system("pause");
	//清理SOCKET环境
	WSACleanup();
	return 0;
}
//获取错误详细信息,并输出
void ErrMsg(DWORD dwErr)
{
	char szErr[1024] = {0};
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), szErr, 1024, NULL);
	printf(szErr);
}

VS2010下出现错误:
1>f:\program\vc++实例精通\23udpclient\23udpclient\23udpclient.cpp(75): error C2664: “FormatMessageW”: 不能将参数 5 从“char [1024]”转换为“LPWSTR”
1>          与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
项目-属性-常规-字符集:改为使用多字节字符集
重新编译出现错误
1>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

项目-属性-配置 属性-清单工具-输入和输出-嵌入清单:是改为否

编译执行:


服务器端

UdpServer.cpp代码:

// 23UdpServer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <stdio.h>
//使用WinSock所需的头文件
#include <WINSOCK.H>
//使用WinSock所需的库文件
#pragma comment(lib, "WSOCK32.LIB")

//程序中要使用的WinSock主版本
#define SOCK_VER 2
//变量和函数声明
SOCKET g_sock = 0;
void ErrMsg(DWORD dwErr);


int _tmain(int argc, _TCHAR* argv[])
{
	//初始化环境
	WSADATA wd = {0};
	int nStart = WSAStartup(MAKEWORD(SOCK_VER, 0), &wd);
	if(nStart = 0)
	{
		return 0;
	}
	if(LOBYTE(wd.wVersion) != 2)
	{
		return 0;
	}
	//创建SOCKET
	g_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(g_sock == INVALID_SOCKET)
	{
		ErrMsg(WSAGetLastError());
		return 0;
	}
	printf("Socket创建成功!\n");
	//绑定到端口28000
	sockaddr_in addr = {0};
	addr.sin_family = AF_INET;
	addr.sin_port = htons(2800);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	int nBind = bind(g_sock, (sockaddr *)&addr, sizeof(addr));
	if(nBind != 0)
	{
		ErrMsg(WSAGetLastError());
		return 0;
	}
	//取得已绑定的端口号
	int nLen = sizeof(addr);
	getsockname(g_sock, (sockaddr *)&addr, &nLen);
	printf("Socket成功绑定到端口:%d,等待数据...\n", ntohs(addr.sin_port));
	//等待并接收信息
	sockaddr_in saClient = {0};
	int nFromLen = sizeof(saClient);
	char szBuff[256] = {0};
	recvfrom(g_sock, szBuff, 256, 0, (sockaddr *)&saClient, &nFromLen);
	printf("收到信息:‘%s’,从%s,%d\n", 
		szBuff, inet_ntoa(saClient.sin_addr), ntohs(saClient.sin_port));
	//向客户端发出回应
	strcpy(szBuff, "OK!");
	int nSent = sendto(g_sock, szBuff, strlen(szBuff) + 1, 0, (sockaddr *)&saClient, sizeof(saClient));
	if(nSent == 0)
		ErrMsg(WSAGetLastError());
	else
		printf("成功发出回应!\n");
	//关闭SOCKET
	closesocket(g_sock);
	//等待用户输入
	system("pause");
	//清理环境
	WSACleanup();
	return 0;
}

//取得错误详细情况,并输出
void ErrMsg(DWORD dwErr)
{
	char szErr[1024] = {0};
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 
		NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
		szErr, 1024, NULL);
	printf(szErr);
}
错误解决同客户端程序的解决方法

编译执行:

此时运行客户端程序,服务器端便可收到客户端发来的信息并作出回应:

客户端收到服务器端做出的回应: