我正在使用WinSock2在C++(Visual Studio 2017(中编写一个客户端-服务器应用程序。我看了一下YouTube教程,做了一个服务器和客户端。启动后,将建立连接。但是,来自服务器的消息不会传输到客户端。
这是我的服务器。
//Server
#pragma comment(lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>
int main() {
//WinSock Startup
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) { //If WSAStartup returns anything ither than 0, than that means an error has occured in the WinSock Startup
MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
SOCKADDR_IN addr; //Address tha the will bind our listening socket to
int addrlen = sizeof(addr); //lenght of the address (required for accept call)
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Broadcast locally
addr.sin_port = htons(1111); //Port
addr.sin_family = AF_INET; //IPv4 Socket
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
listen(sListen, SOMAXCONN); //Places sListen socket in a state in which is in listening for an incoming connection. Note: SOMAXCONN = Socket Outstanding Max Connections
SOCKET newConnection; // Socket to hold the client's connection
newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection
if (newConnection == 0) { //If accepting the client's connection failed
std::cout << "Failed to accept the client's connection" << std::endl;
}
else { //If client connection properly accepted
std::cout << "Client connected!" << std::endl;
char MOID[256] = "Welcome! This is a Message of the Day."; //Create buffer with message of the day
send(newConnection, MOID, sizeof(MOID), NULL); //Send MOID buffer
}
system("pause");
return 0;
}
这就是这样一位客户。
//Client
#pragma comment (lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>
int main() {
//WinSock Startup
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) { //If WSAStartup returns anything ither than 0, than that means an error has occured in the WinSock Startup
MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
SOCKADDR_IN addr; //Address to be binded to our Connection socket
int sizeofaddr = sizeof(addr); //Need sizeofaddr for the connect function
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Address = localhoct (this pc)
addr.sin_port = htons(1111); //Port = 1111
addr.sin_family = AF_INET; //IPv4 Socket
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set connection socket
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) { //If we are unable to connect...
MessageBoxA(NULL, "Failed to connect", "Error", MB_OK | MB_ICONERROR);
return 0; //Failed to connect
}
std::cout << "Connected!" << std::endl;
char MOID[256];
recv(Connection, MOID, sizeof(MOID), NULL); //Recieve Message of the day buffer into MOID array
std::cout << "MOID:" << std::endl;
system("pause");
return 0;
}
这个消息应该被发送:";欢迎这是今天的信息"请告诉我为什么不发送消息,以及我如何解决这个问题?
应该传输此消息:"欢迎这是今天的信息">
您的期望是错误的。TCP套接字是一个流套接字(如SOCK_stream参数所建议的(,这意味着它具有某些属性。对于流,这意味着数据将按照发送时的顺序接收(否则会出现错误(。但并没有人保证你们会把整个信息作为一个数据包。您可以逐字节或2字节一组地获取它们,也可以获取整个消息或任何其他变体。因此,您的程序应该在循环中处理任何读取数据,直到您得到完整的消息。你怎么知道收到了整条信息?这取决于您——有些提前发送消息大小,有些使用消息结束标记(可能是消息的' '
符号(。但期望你们在一次拍摄中得到完整的信息是错误的,这是行不通的。除此之外,您还需要检查recv()
返回的内容,即它接收了多少字节,或者是否发生了任何错误。