套接字 C++:接收函数 returns -1
Socket c++: recv function returns -1
我正在尝试编写一个与 windows 服务器通信的简单 android 客户端。
我正在使用套接字来实现这一点,到目前为止,我一直在使用 Linux 机器(android 客户端和 linux 服务器)测试所有内容。到目前为止,一切正常。现在我试图在 windows(服务器)上设置它,我当然注意到我必须稍微更改我的代码(如果不只是包含 ^^')。
无论如何,我的问题是我的 recv 函数 returns -1 虽然它应该读取一些东西但由于某种原因它没有。
下面是我如何使用我的 recv 函数(编辑:现在是整个服务器代码):
int tcp_server::start_listening()
{
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
printf("Server: The Winsock dll not found!\n");
WSACleanup();
return 0;
}
else
{
printf("Server: The Winsock2 dll found \n");
}
sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sSock == INVALID_SOCKET)
{
printf("Server: Error initializing socket!n");
WSACleanup();
return 0;
}
sockaddr_in service,client ;
service.sin_family = AF_INET;
service.sin_port = htons(port);
service.sin_addr.s_addr = INADDR_ANY;
if(bind(sSock,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("Server: Error binding socket to portn");
WSACleanup();
return 0;
}
/* wait for incoming connections */
if(listen(sSock,10)==SOCKET_ERROR)
printf("listen(): Error listening on socket %d\n", WSAGetLastError());
else
{
printf("Server: Waiting for connections...\n");
}
/* accept connections */
AcceptSocket;
printf("Server: Waiting for a client to connect...\n");
AcceptSocket = accept(sSock, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(sSock);
WSACleanup();
return 1;
} else {
wprintf(L"Client connected.\n");
acceptConns();
}
closesocket(sSock);
return 0;
}
int tcp_server::acceptConns()
{
sockaddr_in from;
bool infinite = true ;
int fromlen=sizeof(from);
int readsize;
char* message;
char* clientmessage = "[=11=]";
string smatrix ;
int ind ;
string tok;
int i = 0 ;
int bytesSent ;
float matrix[16] ;
while( (readsize = recv(AcceptSocket, clientmessage, 2000, 0))!= 0 ){
message = "ack";
cout << "Writing ACK" << endl ;
smatrix = clientmessage ;
std::stringstream ss(smatrix);
cout << smatrix << endl ;
while(getline(ss, tok, ',') && i < 16 ){
matrix[i] = static_cast<float>(::atof(tok.c_str()));
i++ ;
}
i = 0 ;
Sleep(1000);
}
if(readsize == 0 ){
cerr << "client disconnected" << endl ;
}
cout << "Socket closed" << endl ;
closesocket(sSock);
WSACleanup();
}
至于我的 android 代码:这里是:
while(closeConnection == false) {
if (connected == true && matrixupdated == true && this.hasMatrixChanged()){
try {
//= new BufferedReader(new InputStreamReader(java.lang.System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String sentence = this.getStringFromMatrix();
outToServer.writeBytes(sentence + "\n");
outToServer.flush();
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.arraycopy(matrix, 0, previousMatrix, 0, 16);
inFromServer.read(serverMsg);
if(serverMsg.equals("ack") == true){
this.serverHasInput = false ;
Log.e("ACK", "ACK");
inFromServer.read(serverMsg); //Wait for the "ok" message from server
if(serverMsg.equals("ok") == false){
Log.e("ERROR IN COM W/ SERV"," DID NOT RECEIVE OK");
}
}
else{
this.serverHasInput = true ;
}
//Log.d("SERVERMSG", "DONE WAITING");
}catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
this.matrixupdated = false ;
}
}
try {
outToServer.flush();
outToServer.close();
inFromServer.close();
clientSocket.close();
}
不幸的是,最后我在控制台中得到的输出是
client disconnected
我猜这可能是一些非常愚蠢的东西,但我一直试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释。
提前感谢您提供的帮助:)。
C++ 代码中的许多错误 - 例如 if (bytesSent = 0)
,这是一个将结果强制转换为布尔值的赋值,因此总是返回 false
。您不注意从 TCP 套接字读取的字节数,假设您在发送时收到一条完整的消息 - 这是错误的,因为您可能正在阅读部分消息,多于一条消息,或介于两者之间的任何消息 - 它是原始字节流。
检查从系统调用显式返回的 -1
,然后检查 errno(3)
的值,例如,strerror(3)
函数找出问题所在。
编辑 0:
您正在尝试使用侦听套接字 sSock
进行数据传输 - 错误 - 它仅用于接受客户端连接请求。使用 AcceptedSocket
,从 accept()
返回的那个。就是客户端的连接。
您应该 reading/writing 的客户端套接字是 Accept() 调用返回的 'AcceptSocket',而不是 'sSock' 服务器套接字!
要么将AcceptSocket的声明移动到一个成员变量中,将其作为参数传递给'acceptConns();',要么启动一个线程到运行 acceptConns,将AcceptSocket作为void*参数传递给pthread_create,(或其他)。
我认为 Remy 和我都强烈怀疑这是你的问题,甚至在你发布接受代码之前:)
哦等等 - Nikloai 的编辑排在第一位 - 给他点赞!
我正在尝试编写一个与 windows 服务器通信的简单 android 客户端。 我正在使用套接字来实现这一点,到目前为止,我一直在使用 Linux 机器(android 客户端和 linux 服务器)测试所有内容。到目前为止,一切正常。现在我试图在 windows(服务器)上设置它,我当然注意到我必须稍微更改我的代码(如果不只是包含 ^^')。 无论如何,我的问题是我的 recv 函数 returns -1 虽然它应该读取一些东西但由于某种原因它没有。
下面是我如何使用我的 recv 函数(编辑:现在是整个服务器代码):
int tcp_server::start_listening()
{
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
printf("Server: The Winsock dll not found!\n");
WSACleanup();
return 0;
}
else
{
printf("Server: The Winsock2 dll found \n");
}
sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sSock == INVALID_SOCKET)
{
printf("Server: Error initializing socket!n");
WSACleanup();
return 0;
}
sockaddr_in service,client ;
service.sin_family = AF_INET;
service.sin_port = htons(port);
service.sin_addr.s_addr = INADDR_ANY;
if(bind(sSock,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("Server: Error binding socket to portn");
WSACleanup();
return 0;
}
/* wait for incoming connections */
if(listen(sSock,10)==SOCKET_ERROR)
printf("listen(): Error listening on socket %d\n", WSAGetLastError());
else
{
printf("Server: Waiting for connections...\n");
}
/* accept connections */
AcceptSocket;
printf("Server: Waiting for a client to connect...\n");
AcceptSocket = accept(sSock, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(sSock);
WSACleanup();
return 1;
} else {
wprintf(L"Client connected.\n");
acceptConns();
}
closesocket(sSock);
return 0;
}
int tcp_server::acceptConns()
{
sockaddr_in from;
bool infinite = true ;
int fromlen=sizeof(from);
int readsize;
char* message;
char* clientmessage = "[=11=]";
string smatrix ;
int ind ;
string tok;
int i = 0 ;
int bytesSent ;
float matrix[16] ;
while( (readsize = recv(AcceptSocket, clientmessage, 2000, 0))!= 0 ){
message = "ack";
cout << "Writing ACK" << endl ;
smatrix = clientmessage ;
std::stringstream ss(smatrix);
cout << smatrix << endl ;
while(getline(ss, tok, ',') && i < 16 ){
matrix[i] = static_cast<float>(::atof(tok.c_str()));
i++ ;
}
i = 0 ;
Sleep(1000);
}
if(readsize == 0 ){
cerr << "client disconnected" << endl ;
}
cout << "Socket closed" << endl ;
closesocket(sSock);
WSACleanup();
}
至于我的 android 代码:这里是:
while(closeConnection == false) {
if (connected == true && matrixupdated == true && this.hasMatrixChanged()){
try {
//= new BufferedReader(new InputStreamReader(java.lang.System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String sentence = this.getStringFromMatrix();
outToServer.writeBytes(sentence + "\n");
outToServer.flush();
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.arraycopy(matrix, 0, previousMatrix, 0, 16);
inFromServer.read(serverMsg);
if(serverMsg.equals("ack") == true){
this.serverHasInput = false ;
Log.e("ACK", "ACK");
inFromServer.read(serverMsg); //Wait for the "ok" message from server
if(serverMsg.equals("ok") == false){
Log.e("ERROR IN COM W/ SERV"," DID NOT RECEIVE OK");
}
}
else{
this.serverHasInput = true ;
}
//Log.d("SERVERMSG", "DONE WAITING");
}catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
this.matrixupdated = false ;
}
}
try {
outToServer.flush();
outToServer.close();
inFromServer.close();
clientSocket.close();
}
不幸的是,最后我在控制台中得到的输出是
client disconnected
我猜这可能是一些非常愚蠢的东西,但我一直试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释。
提前感谢您提供的帮助:)。
C++ 代码中的许多错误 - 例如 if (bytesSent = 0)
,这是一个将结果强制转换为布尔值的赋值,因此总是返回 false
。您不注意从 TCP 套接字读取的字节数,假设您在发送时收到一条完整的消息 - 这是错误的,因为您可能正在阅读部分消息,多于一条消息,或介于两者之间的任何消息 - 它是原始字节流。
检查从系统调用显式返回的 -1
,然后检查 errno(3)
的值,例如,strerror(3)
函数找出问题所在。
编辑 0:
您正在尝试使用侦听套接字 sSock
进行数据传输 - 错误 - 它仅用于接受客户端连接请求。使用 AcceptedSocket
,从 accept()
返回的那个。就是客户端的连接。
您应该 reading/writing 的客户端套接字是 Accept() 调用返回的 'AcceptSocket',而不是 'sSock' 服务器套接字!
要么将AcceptSocket的声明移动到一个成员变量中,将其作为参数传递给'acceptConns();',要么启动一个线程到运行 acceptConns,将AcceptSocket作为void*参数传递给pthread_create,(或其他)。
我认为 Remy 和我都强烈怀疑这是你的问题,甚至在你发布接受代码之前:)
哦等等 - Nikloai 的编辑排在第一位 - 给他点赞!