无法从服务器发送消息(C++套接字)



我是C++ Socket的新手,我的服务器无法向其客户端发送消息。send()函数总是返回-1,似乎accpSocket有问题。然而,客户可以很顺利地做到这一点,我不知道出了什么问题。请帮助我,非常感谢!

服务器

#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#include<sdkddkver.h>
#include<winsock.h>
using namespace std;
int main() {
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
int port = 2403;
WSADATA wsaData;
int wsaerr;
//Step 1: Set up dll
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);

if (wsaerr)
cout << "The winsock dll not found";
else {
cout << "The winsock dll foundn";
cout << "Winsock dll status: " << wsaData.szSystemStatus << endl;
}
//Step 2: Set up server socket
serverSocket = INVALID_SOCKET;
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (serverSocket == INVALID_SOCKET) {
cout << "Error at socket: " << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Server socket successfull!n";

//Step 3: Binding socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.S_un.S_addr = INADDR_ANY;
service.sin_port = htons(port);
if (bind(serverSocket, (sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) {
cout << "Binding failed! " << WSAGetLastError();
return 0;
}
else
cout << "Binding complete!n";

// Step 4: Listen to the connections
if (listen(serverSocket, 1) == SOCKET_ERROR) {
cout << "Listen failed! " << WSAGetLastError();
return 0;
}
else
cout << "Waiting for connections ...";

SOCKET accpSocket = accept(serverSocket, NULL, NULL);
if (accpSocket == INVALID_SOCKET) {
cout << "Accepting failed! " << WSAGetLastError();
WSACleanup();
return -1;
}
else
cout << "Accept connection!n";

char recvMess[2000];
char sendMess[2000];
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
cout << "Client: " << recvMess << endl;
cout << "Server: ";
cin.getline(sendMess, 2000);
int bytesend = send(acceptSocket, sendMess, 2000, 0);
if (bytesend <= 0)
cout << "Unsent";


return 0;
}

客户

#include<iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
using namespace std;
int main() {
int port = 2403;
WSADATA wsaData;
int wsaerr;
SOCKET clientSocket;
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);
if (wsaerr)
cout << "Winsock dll not found!";
else {
cout << "Winsock dll is ok!n";
cout << "Status: " << wsaData.szSystemStatus << endl;
}
clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
cout << "Set up client socket failed" << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Set up complete!n";
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_port = htons(port);
if (inet_pton(clientService.sin_family, "127.0.0.1", &clientService.sin_addr) <= 0) {
cout << "Invalid address!";
return -1;
}
if ((connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService))) == SOCKET_ERROR) {
cout << "Connection failed!n";
WSACleanup();
return 0;
}
else
cout << "Connection complete!n";
char sendMess[2000];
char recvMess[2000];
cout << "Client: ";
cin.getline(sendMess, 2000);
int bytesend = send(clientSocket, sendMess, 2000, 0);
int byterecv = recv(clientSocket, recvMess, 2000, 0);
if (byterecv <= 0)
cout << "Nothing";
else
cout << "Server" << recvMess << endl;
return 0;
}
int bytesend = send(acceptSocket, sendMess, 2000, 0);

没有发送到已连接的套接字。acceptSocketmain的顶部定义,然后忽略,直到调用send

作为一般的经验法则,保持变量定义接近第一次使用。

在服务器

SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Killlllll meeeeee!!!! 

删除acceptSocket以防止将来出现错误。

int bytesend = send(acceptSocket, sendMess, 2000, 0);

用实际接受的套接字accpSocket替换acceptSocket

指出:

永远不要忽略返回码。

int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);

如果套接字断开连接,可能失败并返回-1或返回0,但是程序仍然会

cout << "Client: " << recvMess << endl;

更糟糕的是,不能保证recvMess将以空终止,流套接字上的recv为您提供套接字可用或可用的最大请求字节数,因此,如果有任何数据读取,请确保byterecvrecvMess中的有效索引,仅读取sizeof(recvMess) - 1字节,然后在打印前强制终止recvMess[byterecv] = '';

send(acceptSocket, sendMess, 2000, 0);发送所有2000字节的sendMess,不管cin.getline(sendMess, 2000);读取了多少字节。使用

send(acceptSocket, sendMess, cin.gcount(), 0);

。如果您想发送空终止符,请添加一个额外的字节(cin.gcount() + 1)。

最新更新