【发布时间】:2015-06-08 15:53:54
【问题描述】:
我正在尝试编写一个与 Windows 服务器通信的简单 android 客户端。 我正在使用套接字来实现这一点,到目前为止,我正在使用 Linux 机器(android 客户端和 linux 服务器)测试所有内容。到目前为止,一切正常。现在我正在尝试在 Windows(服务器)上设置它,我当然注意到我必须稍微更改我的代码(如果不只是包含 ^^')。 无论如何,我的问题是我的 recv 函数返回 -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 = "\0";
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();
}
至于我的安卓代码:这里是:
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();
}
最后不幸的是我在控制台中得到的输出
客户端断开
我猜这可能是一些非常愚蠢的东西,但我一直试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释。
提前感谢您提供的帮助:)。
【问题讨论】:
-
OK,当系统调用失败时,WSAGetLastError() 的结果是什么?
-
'试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释' 真的??? MSDN:如果没有发生错误,recv 返回接收到的字节数,buf 参数指向的缓冲区将包含接收到的数据。如果连接已正常关闭,则返回值为零。否则,返回 SOCKET_ERROR 的值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。'
-
我投票结束这个问题,因为 OP 没有阅读失败的系统调用的 MSDN 文档。
-
另外,你的缓冲区 'char* clientmessage = "\0";'是一个字符串文字,它太短而不能容纳 2000 个字符,是只读的,会导致 recv() 失败。
-
服务器代码中的这一行
cout << recv(sSock, clientmessage, 2000, 0) << endl ;可能会读取所有内容,而不会为下一条语句while( (readsize = recv(sSock, clientmessage, 2000, 0))!= 0 )留下任何内容。在进入 while 循环时,如果没有任何东西可以接收,readsize将被设置为 0,因此client disconnected输出。
标签: c++ c sockets winsock2 recv