先用udp构建一个socket通信示例为后面编写iocp服务器做准备
先编写服务器 3步 初始化套接字 绑定端口 收数据
#include <stdio.h> #include <winsock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //1.初始化套接字 SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //2.绑定端口 sockaddr_in addr; //转换大小尾 addr.sin_family = AF_INET; addr.sin_port = htons(0x12345); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); if (bind(s, (sockaddr*)&addr, sizeof(addr)) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //域名转换 //struct addrinfo hints = { 0 }; //hints.ai_family = AF_INET; //struct addrinfo* resulut = NULL; //struct addrinfo* ptr = NULL; //if (getaddrinfo("localhost", NULL, &hints, &resulut)) //{ // printf("getaddrinfo error"); // return 0; //} ////是个链表 //struct sockaddr_in* sockaddr_ipv4; ////循环遍历所有ip地址 //for (ptr = resulut; ptr != NULL; ptr = ptr->ai_next) //{ // sockaddr_ipv4 = (struct sockaddr_in*)ptr->ai_addr; ///* printf("\tIPv4 address %s\n", // inet_ntoa(sockaddr_ipv4->sin_addr));*/ // char szIP[128]; // inet_ntop(AF_INET, &sockaddr_ipv4->sin_addr, szIP, sizeof(szIP)); // printf("%s", szIP); //} //3.收发数据 printf("recvfrom"); char szBuffer[256]; sockaddr_in caddr; //客户端地址 int nLength = sizeof(caddr); while (1) { int nRet=recvfrom(s, szBuffer,sizeof(szBuffer),0,(sockaddr *)&caddr, &nLength); if (nRet==SOCKET_ERROR) { printf("recvfrom error %08X", WSAGetLastError()); break; }
szBuffer[nRet] = '\0';
printf("data:%s bytes:%d\n", szBuffer, nRet); } //关闭初始化 closesocket(s); //反初始化库 WSACleanup(); }
客户端 2步 初始化套接字 发消息
#include <stdio.h> #include <winsock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //1.初始化套接字 SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in addr; //转换大小尾 addr.sin_family = AF_INET; addr.sin_port = htons(0x12345); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); //2.收发数据 char szBuffer[256]; while (1) { scanf_s("%s", szBuffer, sizeof(szBuffer)); //发送数据 sendto(s, szBuffer, strlen(szBuffer), 0, (sockaddr*)&addr, sizeof(addr)); } //关闭初始化 closesocket(s); //反初始化库 WSACleanup(); }
丢包严重。。
单线程的简单模拟通信, socket 离不开多线程的 不可能只有一个socket结构 后面要把socket 封装成类 为每一个客户端实例化
这样代码服务端
#include <stdio.h> #include <winsock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") DWORD WINAPI RecvThread(LPVOID lpParameter)//接收消息线程 { SOCKET s = (SOCKET)lpParameter; char szBuffer[256]; sockaddr_in caddr; //客户端地址 int nLength = sizeof(caddr); while (1) { //接收 返回接收长度 int nRet = recvfrom(s, szBuffer, sizeof(szBuffer), 0, (sockaddr*)&caddr, &nLength); if (nRet == SOCKET_ERROR) { printf("recvfrom error %08X", WSAGetLastError()); break; } szBuffer[nRet] = '\0'; char IPdotdec[20]; //存放点分十进制IP地址 struct in_addr s; // IPv4地址结构体 inet_ntop(AF_INET, &caddr.sin_addr, IPdotdec, 16);//点阵转换ip printf("ip:%s port:%d data:%s bytes:%d\n", IPdotdec, caddr.sin_port, szBuffer, nRet); } } int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //1.初始化套接字 SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //2.绑定端口 sockaddr_in addr; //转换大小尾 addr.sin_family = AF_INET; addr.sin_port = htons(0x12345); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); if (bind(s, (sockaddr*)&addr, sizeof(addr)) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //3.收发数据 printf("recvfrom、\n"); CreateThread(NULL, 0, RecvThread, (LPVOID)s, 0, NULL); char szBuffer[256]; sockaddr_in caddr; //客户端地址 int nLength = sizeof(caddr); while (1) { //接收 返回接收长度 int nRet = recvfrom(s, szBuffer, sizeof(szBuffer), 0, (sockaddr*)&caddr, &nLength); if (nRet == SOCKET_ERROR) { printf("recvfrom error %08X", WSAGetLastError()); break; } szBuffer[nRet] = '\0'; char IPdotdec[20]; //存放点分十进制IP地址 inet_ntop(AF_INET, &caddr.sin_addr, IPdotdec, 16);//点阵转换ip printf("ip:%s port:%d data:%s bytes:%d\n", IPdotdec, caddr.sin_port, szBuffer, nRet); sendto(s,"ok", strlen("ok"), 0, (sockaddr*)&caddr, sizeof(caddr)); } //关闭初始化 closesocket(s); //反初始化库 WSACleanup(); }
代码端
#include <stdio.h> #include <winsock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") DWORD WINAPI RecvThread(LPVOID lpParameter)//接收消息线程 { SOCKET s = (SOCKET)lpParameter; char szBuffer[256]; sockaddr_in caddr; //客户端地址 int nLength = sizeof(caddr); while (1) { //接收 返回接收长度 int nRet = recvfrom(s, szBuffer, sizeof(szBuffer), 0, (sockaddr*)&caddr, &nLength); if (nRet == SOCKET_ERROR) { printf("recvfrom error %08X", WSAGetLastError()); break; } szBuffer[nRet] = '\0'; char IPdotdec[20]; //存放点分十进制IP地址 struct in_addr s; // IPv4地址结构体 inet_ntop(AF_INET, &caddr.sin_addr, IPdotdec, 16);//点阵转换ip printf("ip:%s port:%d data:%s bytes:%d\n", IPdotdec, caddr.sin_port, szBuffer, nRet); } } int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup error%08X", WSAGetLastError()); return 0; } //1.初始化套接字 SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in addr; //转换大小尾 addr.sin_family = AF_INET; addr.sin_port = htons(0x12345); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); //2.收发数据 char szBuffer[256]; int flag = 1; while (1) { scanf_s("%s", szBuffer, sizeof(szBuffer));
fflush(stdin); //发送数据 sendto(s, szBuffer, strlen(szBuffer), 0, (sockaddr*)&addr, sizeof(addr)); //char IPdotdec[20]; //存放点分十进制IP地址 //inet_ntop(AF_INET, &addr.sin_addr, IPdotdec, 16); //printf("ip :%s port:%d ", IPdotdec, addr.sin_port); if (flag) { CreateThread(NULL, 0, RecvThread, (LPVOID)s, 0, NULL); flag = 0; } } //关闭初始化 closesocket(s); //反初始化库 WSACleanup(); }