以下是针对Socket套接字编程中如下图中所示的未定义的问题(undefined reference to imp_WSAStartup' imp_socket'...
win解决方式
-
首先安装g++编译器,如果没有可参考以下网页,首先在cmd(快捷键win+R打开cmd)中输入
g++ -v
查看g++版本
安装网页:
[0] https://cloud.tencent.com/developer/article/1500352 Windows下 gcc/g++的安装与配置
-
在当前目录下启用cmd,或者使用cd命令切换到对应的目录文件夹
-
使用命令编译产生exe文件
g++ TCPClient.cpp -o TCPClinet.exe -lws2_32
-o 后跟着产生exe文件的名称
-lws2_32 是一种链接库,该库对应ws2_32.dll,提供了网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程。
-
在文件下运行相应的exe文件(例:TCPClinet.exe)
-
先运行服务器端,再运行客户端
所有代码文件打包在github上:zsflalala/Socket-TCP-UDP · GitHub
MultiMessage
TCPServer
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#define BufLen 1024
#define port 1234
int main()
{
// 初始化DLL
WSAData wsadata;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsadata);
printf("IP包最大长度:%hu\n", wsadata.iMaxUdpDg);
if (iResult != NO_ERROR) //NO_ERROR值为0
{
printf("WSAStartupfailedwitherror:%ld\n", iResult);
return 1;
}
// 创建套接字 (socket)
SOCKET servSock = socket(PF_INET, SOCK_STREAM, 0);
if (servSock == INVALID_SOCKET)
{
printf("socketfailedwitherror:%d\n", WSAGetLastError());
//终止dll的使用
WSACleanup();
return 1;
}
// 准备通信地址
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET; //IPV4协议
saddr.sin_port = htons(1234); //端口 host to network short 主机字节序转网络字节序 传入的类型为short
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 绑定地址与socket(bind)
if (bind(servSock, (sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
{
printf("bindfailedwitherror:%ld\n", WSAGetLastError());
closesocket(servSock);
WSACleanup();
return 1;
}
// 监听 (listen)
if (listen(servSock, 20) == SOCKET_ERROR) /*设请求队列上限为20 当请求队列满时,就不再接收新的请求 对于客户端会收到 WSAECONNREFUSED 错误。*/
{
printf("bindfailedwitherror:%ld\n", WSAGetLastError());
closesocket(servSock);
WSACleanup();
return 1;
};
// 等待客户端连接 (accept)
int nSize = sizeof(SOCKADDR);
struct sockaddr_in clntAddr; //用于接受客户端地址信息
memset(&clntAddr, 0, sizeof(clntAddr));
printf("Waiting for client to connect...\n");
SOCKET clienSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
if (clienSock == INVALID_SOCKET)
{
printf("accept failed with error:%ld\n", WSAGetLastError());
closesocket(servSock);
WSACleanup();
return 1;
}
else
{
printf("client:%s:%hu have connected;socket=%d\n", inet_ntoa(clntAddr.sin_addr), ntohs(clntAddr.sin_port), clienSock);
}
printf("Waiting for client to send message...\n");
// 收发数据 (recv & send)
char RecvBuf[BufLen];
char SendBuf[BufLen];
while(true)
{
// 接收数据 (recv)
ZeroMemory(RecvBuf,BufLen);
if (SOCKET_ERROR == recv(clienSock, RecvBuf, BufLen, 0))
{
closesocket(clienSock);
closesocket(servSock);
WSACleanup();
printf("get recv error");
system("pause");
return false;
}
printf("client:%s\n",RecvBuf);
if(strcmp(RecvBuf,"exit") == 0)
{
break;
}
// 发送数据 (send)
ZeroMemory(SendBuf,BufLen);
printf("server:");
scanf("%s",SendBuf);
if (SOCKET_ERROR == send(clienSock, SendBuf, BufLen, 0))
{
closesocket(clienSock);
closesocket(servSock);
WSACleanup();
printf("get send error");
system("pause");
return false;
}
}
printf("\nClient have disconnected.\n");
// 退出
closesocket(clienSock);
closesocket(servSock);
WSACleanup();
system("pause");
return 0;
}
TCPClient:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#define BufLen 1024
#define port 1234
int main(){
// 初始化DLL
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
// 创建套接字
SOCKET clienSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
// 准备通信地址
struct sockaddr_in sockAddr;
sockAddr.sin_family = PF_INET;
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sockAddr.sin_port = htons(port);
// 连接服务器
connect(clienSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
printf("you have connected the server!\n");
// 收发数据
char SendBuf[BufLen]; // 发送数据缓冲区
char RecvBuf[BufLen]; // 接受数据缓冲区
while(true){
// 发送数据
printf("client:");
scanf("%s",SendBuf);
send(clienSock, SendBuf, BufLen, 0);
if(strcmp(SendBuf,"exit") == 0)
{
break;
}
// 接收数据
ZeroMemory(RecvBuf, BufLen); // 缓冲区清零
recv(clienSock, SendBuf, BufLen, 0);
printf("server:%s\n",SendBuf);
}
printf("\nExit successfully! Bye!\n");
//关闭套接字
closesocket(clienSock);
//终止使用 DLL
WSACleanup();
system("pause");
return 0;
}
小写转大写
TCPServer:
//服务器
#include <WINSOCK2.H> //socket 头文件
#include <iostream>
#pragma comment(lib, "WS2_32.lib") // 加环境配置 -lWS2_32
#define port 4010 // 端口号
#define BufLen 1024 // 缓冲区大小
using namespace std;
int main()
{
WSADATA wsaData;
// 1 启用并初始化windows socket(WSAStartup)
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) //成功返回0
{
return false;
}
// 2 创建套接字(socket)
SOCKET LinkSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 服务器套接字
if (INVALID_SOCKET == LinkSocket) // INVALID_SOCKET 无效套接字
{
closesocket(LinkSocket);
WSACleanup();
return false;
}
// 3 准备通信地址
sockaddr_in ServerAddr; // 服务器地址
ServerAddr.sin_family = AF_INET;
// ServerAddr.sin_port = htons(port);
// ServerAddr.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY 任意可用地址
ServerAddr.sin_port = htons(1234);
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ServerAddr_len = sizeof(ServerAddr);
// 4 绑定地址与socket(bind)
if (SOCKET_ERROR == bind(LinkSocket, (SOCKADDR *)&ServerAddr, ServerAddr_len))
{
closesocket(LinkSocket);
WSACleanup();
return false;
}
//5 监听 (listen)
if (SOCKET_ERROR == listen(LinkSocket, SOMAXCONN))
{
closesocket(LinkSocket);
WSACleanup();
return false;
}
// 6 等待客户端连接(accpet)
sockaddr_in ClientAddr;
int ClientAddr_len = sizeof(ClientAddr);
cout << "等待客户端连接中..." << endl;
SOCKET ServerSocket = accept(LinkSocket, (SOCKADDR *)&ClientAddr, &ClientAddr_len);
if (INVALID_SOCKET == ServerSocket)
{
closesocket(ServerSocket);
closesocket(LinkSocket);
WSACleanup();
return false;
}
cout << "客户端连接成功!" << endl
<< endl;
// 7 接收数据 (recv)
char RecvBuf[BufLen];
ZeroMemory(RecvBuf, BufLen);
cout << "准备接收来自客户端数据..." << endl;
if (SOCKET_ERROR == recv(ServerSocket, RecvBuf, BufLen, 0))
{
closesocket(ServerSocket);
closesocket(LinkSocket);
WSACleanup();
return false;
}
cout << "服务器接收消息成功!" << endl
<< endl;
// 8 发送数据 (send)
char SendBuf[BufLen];
char *p = RecvBuf, *q = SendBuf;
while (*p != '\0')
*q++ = *p++ - 'a' + 'A';
cout << "准备发送数据报给客户端..." << endl;
if (SOCKET_ERROR == send(ServerSocket, SendBuf, BufLen, 0))
{
closesocket(ServerSocket);
closesocket(LinkSocket);
WSACleanup();
return false;
}
cout << "服务器发送消息成功!" << endl
<< endl;
// 9 准备退出
cout << "准备退出..." << endl;
closesocket(ServerSocket);
closesocket(LinkSocket);
WSACleanup();
system("pause");
return 0;
}
TCPClient:
//客户端
#include <WINSOCK2.H>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#define port 1234 // 端口号
#define BufLen 1024 // 缓冲区大小
using namespace std;
int main()
{
WSADATA wsaData;
// 1 启用并初始化windows socket(WSAStartup)
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) //成功返回0
{
return false;
}
// 2 创建套接字(socket)
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == ClientSocket)
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
// 3 准备通信地址
sockaddr_in ServerAddr; // 服务器地址
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(port);
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 4 连接服务器 (connect)
cout << "准备连接服务器..." << endl;
if (SOCKET_ERROR == connect(ClientSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)))
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
cout << "连接成功!" << endl
<< endl;
// 5 发送数据 (send)
char SendBuf[BufLen]; // 发送数据缓冲区
cout << "请输入小写字符串:" << endl;
cin >> SendBuf;
cout << "准备发送数据报给服务器..." << endl;
if (SOCKET_ERROR == send(ClientSocket, SendBuf, BufLen, 0))
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
cout << "客户端发送消息成功!" << endl
<< endl;
// 6 接收数据 (recv)
char RecvBuf[BufLen]; // 接受数据缓冲区
ZeroMemory(RecvBuf, BufLen); // 缓冲区清零
cout << "准备接收来自服务器的数据报..." << endl;
if (SOCKET_ERROR == recv(ClientSocket, RecvBuf, BufLen, 0))
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
cout << "客户端接收消息成功!" << endl
<< endl;
cout << "服务器消息为:" << endl;
cout << RecvBuf << endl
<< endl;
// 7 准备退出
cout << "准备退出..." << endl;
closesocket(ClientSocket);
WSACleanup();
system("pause");
return 0;
}
UDPServer:
//服务器
#include <WINSOCK2.H> //socket 头文件
#include <iostream>
#pragma comment(lib, "WS2_32.lib") // 加环境配置 -lWS2_32
#define port 4000 // 端口号
#define BufLen 1024 // 缓冲区大小
using namespace std;
int main()
{
WSADATA wsaData;
// 1 启用并初始化windows socket(WSAStartup)
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) //成功返回0
{
return false;
}
// 2 创建套接字(socket)
SOCKET ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // 服务器套接字
if (INVALID_SOCKET == ServerSocket) // INVALID_SOCKET 无效套接字
{
closesocket(ServerSocket);
WSACleanup();
return false;
}
// 3 准备通信地址
sockaddr_in ServerAddr; // 服务器地址
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(1234);
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ServerAddr_len = sizeof(ServerAddr);
// 4 绑定地址与socket(bind)
if (SOCKET_ERROR == bind(ServerSocket, (SOCKADDR *)&ServerAddr, ServerAddr_len))
{
closesocket(ServerSocket);
WSACleanup();
return false;
}
// 5 接收数据(recvfrom)
char RecvBuf[BufLen];
ZeroMemory(RecvBuf, BufLen);
sockaddr_in ClientAddr;
int ClientAddr_len = sizeof(ClientAddr);
cout << "准备接收来自客户端数据..." << endl;
if (SOCKET_ERROR == recvfrom(ServerSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&ClientAddr, &ClientAddr_len))
{
closesocket(ServerSocket);
WSACleanup();
return false;
}
cout << "服务器接收消息成功!" << endl
<< endl;
// 6 发送数据(sendto)
char SendBuf[BufLen];
char *p = RecvBuf, *q = SendBuf;
while (*p != '\0')
*q++ = *p++ - 'a' + 'A';
cout << "准备发送数据报给客户端..." << endl;
if (SOCKET_ERROR == sendto(ServerSocket, SendBuf, BufLen, 0, (SOCKADDR *)&ClientAddr, ClientAddr_len))
{
closesocket(ServerSocket);
WSACleanup();
return false;
}
cout << "服务器发送消息成功!" << endl
<< endl;
// 7 准备退出
cout << "准备退出..." << endl;
closesocket(ServerSocket);
WSACleanup();
system("pause");
return 0;
}
UDPClient:
//客户端
#include <WINSOCK2.H> //socket 头文件
#include <iostream>
#pragma comment(lib, "WS2_32.lib") // 加环境配置 -lWS2_32
#define port 4000 // 端口号
#define BufLen 1024 // 缓冲区大小
using namespace std;
int main()
{
WSADATA wsaData;
// 1 启用并初始化windows socket(WSAStartup)
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) //成功返回0
{
return false;
}
// 2 创建套接字(socket)
SOCKET ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // 客户端套接字由操作系统分配端口
if (INVALID_SOCKET == ClientSocket) // INVALID_SOCKET 无效套接字
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
// 3 准备通信地址
sockaddr_in ServerAddr; // 服务器地址
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(1234);
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ServerAddr_len = sizeof(ServerAddr);
// 4 发送数据 (sendto)
char SendBuf[BufLen]; // 发送数据缓冲区
cout << "请输入小写字符串:" << endl;
cin >> SendBuf;
cout << "准备发送数据报给服务器..." << endl;
if (SOCKET_ERROR == sendto(ClientSocket, SendBuf, BufLen, 0, (SOCKADDR *)&ServerAddr, ServerAddr_len)) // SOCKET_ERROR = -1
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
cout << "客户端发送消息成功!" << endl
<< endl;
// 5 接收数据(recvfrom)
char RecvBuf[BufLen]; // 接受数据缓冲区
ZeroMemory(RecvBuf, BufLen); // 缓冲区清零
cout << "准备接收来自服务器的数据报..." << endl;
if (SOCKET_ERROR == recvfrom(ClientSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&ServerAddr, &ServerAddr_len)) // SOCKET_ERROR = -1
{
closesocket(ClientSocket);
WSACleanup();
return false;
}
cout << "客户端接收消息成功!" << endl
<< endl;
cout << "服务器消息为:" << endl;
cout << RecvBuf << endl
<< endl;
// 6 准备退出
cout << "准备退出..." << endl;
closesocket(ClientSocket);
WSACleanup();
system("pause");
return 0;
}