[英]Can't send Message from Server( C++ Socket)
I'm new to C++ Socket
and my Server can't send message to its client.我是
C++ Socket
的新手,我的服务器无法向其客户端发送消息。 The send()
function return -1 always and it seems to have a problem with accpSocket
. send()
函数总是返回 -1,而且accpSocket
似乎有问题。 However Client can do that smoothly and I don't know what's wrong.但是客户可以顺利地做到这一点,我不知道出了什么问题。 Please help me thank you so much!
请帮帮我,非常感谢!
Server服务器
#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 found\n";
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;
}
Client客户
#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);
is not sending to a connected socket.没有发送到连接的套接字。
acceptSocket
was defined at the top of main
and then ignored up until the call to send
acceptSocket
在main
的顶部定义,然后被忽略,直到调用send
As a general rule of thumb, keep variable definition close to first use.作为一般经验法则,保持变量定义接近第一次使用。
In the server at在服务器中
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Killlllll meeeeee!!!!
remove acceptSocket
to prevent future mistakes and in删除
acceptSocket
以防止将来出现错误并在
int bytesend = send(acceptSocket, sendMess, 2000, 0);
replace acceptSocket
with the socket that was actually accepted, accpSocket
.将
acceptSocket
替换为实际接受的套接字accpSocket
。
Side notes:旁注:
Never ignore the return codes.永远不要忽略返回码。
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
could fail and return -1 or return 0 if the socket was disconnected, yet the program will still如果套接字断开连接,可能会失败并返回 -1 或返回 0,但程序仍将
cout << "Client: " << recvMess << endl;
And worse, there's no guarantee that recvMess
will be null-terminated, recv
on a streaming socket gives you what the socket has available or becomes available up to the maximum number of bytes requested, so if there is any data read, make sure byterecv
is a valid index in recvMess
by only reading sizeof(recvMess) - 1
bytes and then forcing termination with recvMess[byterecv] = '\0';
更糟糕的是,不能保证
recvMess
将以空值终止,流式套接字上的recv
为您提供套接字可用或可用的最大字节数,因此如果读取任何数据,请确保byterecv
是通过仅读取sizeof(recvMess) - 1
个字节然后使用recvMess[byterecv] = '\0';
强制终止来获得recvMess
中的有效索引; before printing.打印前。
send(acceptSocket, sendMess, 2000, 0);
sends all 2000 bytes of sendMess regardless of how many bytes were read with cin.getline(sendMess, 2000);
无论使用
cin.getline(sendMess, 2000);
. . Use
利用
send(acceptSocket, sendMess, cin.gcount(), 0);
instead.反而。 Add on an extra byte (
cin.gcount() + 1
) if you want to send the null terminator.如果要发送空终止符,请添加一个额外的字节(
cin.gcount() + 1
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.