c语言 - 服务器未绑定到客户端



我正在用c++编码,我需要从服务器(Raspberry Pi 4)向客户端(我的计算机)发送数据(文本)。

经过大量的研究,我已经建立了一个代码,接近互联网上可用的。但是,在编译调试server.cppclient.cpp文件时,虽然没有明显的错误,但是从客户端向服务器发送数据和从服务器向客户端发送数据都失败了。

实际上,对于客户端文件,我得到错误10060,这实际上是可以理解的,因为服务器无法链接到它。

所以,我知道问题是与我的服务器文件(更准确地说,与bind()功能)。但令人惊讶的是,当我使用perror()函数来检查我正在处理的错误类型时,我得到"No error"。我一直在试图找出原因,但到目前为止我还是不清楚。我有一个理论,问题可能与我的IP地址或引用端口有关。

有人能帮我一下吗?

以下是server.cppclient.cpp文件中的代码片段。

server.cpp:

#include <string.h>
#include <WS2tcpip.h>
#include <winsock2.h> 
#include <cstdio> 
#include <errno.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{   //Defining variables
int my_socket, new_socket, c,error,bind_number;
struct sockaddr_in server, client;
char* message;
char host[NI_MAXHOST];// Client's remote name
char service[NI_MAXSERV];// service i.e port the client is connected on
WSADATA wsdata;
WORD ver = MAKEWORD(2, 2);
int wsok = WSAStartup(ver, &wsdata);
PCWSTR client_IP_Addr=L"192.168.0.102";
char connect[] = "connected on port";
// initialize winsock
if (wsok != 0)
printf( "can't Initialize winsock! Quitting...n");
else
printf("winsock successfully initialized !n");
//Create socket
my_socket = socket(AF_INET, SOCK_STREAM, 0);
if (my_socket == -1) printf("Could not create socket");
//Geting client ip adress and port 
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = InetPton(AF_INET,client_IP_Addr, &server.sin_addr); //inet_addr("192.168.0.1");//client_ip
server.sin_port = htons(4024);// not sure 
//Bind
bind_number = bind(my_socket, (struct sockaddr*)&server, sizeof(server));
if (bind_number < 0) 
//puts("bind failed due to error");
perror("bind failed due to error:");
return 1;
puts("bind done");
...

client.cpp:

#include <WS2tcpip.h>
#include <winsock2.h> 
#include <cstdio>
#include <string>
#pragma comment(lib,"ws2_32.lib") 

int main(int argc, char* argv[])
{
// ********************************************************
// Defining the variables
// ********************************************************
WSADATA win32_initialisation;
int error, caracter_lenght;
char message[65535];
char server_reply[65535];
SOCKET my_socket;
SOCKADDR_IN destination_information;
PCWSTR server_IP_Addr =L"0.0.0.0";
printf("nHello, it's the client talking heren");
// ********************************************************
// Winsock  Initialisation
// ********************************************************
error = WSAStartup(MAKEWORD(2, 2), &win32_initialisation);
if (error != 0)
printf("nSorry, can't initialise Winsock due to error : %d %d", error, WSAGetLastError());
else
printf("nWSAStartup  : OK");
// ********************************************************
// Opening Socket
// ********************************************************
my_socket = socket(AF_INET, SOCK_STREAM, 0);
if (my_socket == INVALID_SOCKET)
printf("nSorry, can't create the socket due to error : %d", WSAGetLastError());
else
printf("nsocket      : OK");
// ********************************************************
// Establishing session opening
// ********************************************************
destination_information.sin_family = AF_INET;
destination_information.sin_addr.s_addr = InetPton(AF_INET, server_IP_Addr, &destination_information.sin_addr);
destination_information.sin_port = htons(22); // Try 631 and 5900 if 22 isn't working
error = connect(my_socket, (struct sockaddr*)&destination_information, sizeof(destination_information));
if (error != 0)
printf("nSorry, couldn't open the TCP session due to error : %d %d", error, WSAGetLastError());
else
printf("nsetsockopt  : OK");
...

如注释所述,这两组代码都有很多问题,即你对IP地址和端口的使用都是错误的。

同样,你的错误处理是不充分的。在一个地方,它甚至坏了。在服务器代码中,如果bind()失败,则调用perror()输出错误(ok),但随后会执行return语句,无论bind()成功还是失败,该语句都会无条件地执行,从而退出进程。调用perror()if块需要添加花括号,然后将return语句移到花括号内。

//Bind
bind_number = bind(my_socket, (struct sockaddr*)&server, sizeof(server));
if (bind_number < 0) { // <-- add
//puts("bind failed due to error");
perror("bind failed due to error:");
return 1; // <-- moved here!
} // <-- add

说了这些,试着像下面这样:

server.cpp:

#include <iostream> 
#include <string> 
#include <WS2tcpip.h>
#include <winsock2.h> 
#pragma comment(lib, "ws2_32.lib")
int main()
{
//Defining variables
SOCKET my_socket, new_socket;
int error;
SOCKADDR_IN server, client;
std::string server_IP_Addr = "0.0.0.0";//"192.168.0.102"
...
// initialize winsock
WSADATA wsdata;
WORD ver = MAKEWORD(2, 2);
error = WSAStartup(ver, &wsdata);
if (error != 0) {
std::cerr << "Sorry, can't initialize Winsock due to error : " << error << "! Quitting...n";
return 1;
}
std::cout << "Winsock successfully initialized!n";

//Create socket
my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (my_socket == INVALID_SOCKET) {
error = WSAGetLastError();
std::cerr << "Sorry, Could not create socket due to error : " << error << "! Quitting...n";
WSACleanup();
return 1;
}
//Prepare the sockaddr_in structure
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
inet_pton(AF_INET, server_IP_Addr.c_str(), &server.sin_addr);
server.sin_port = htons(4024);
//Bind
if (bind(my_socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
error = WSAGetLastError();
std::cerr << "Sorry, Could not bind socket due to error : " << error << "! Quitting...n";
closesocket(my_socket);
WSACleanup();
return 1;
}
std::cout << "Bind successful!n";
...
}

client.cpp:

#include <iostream>
#include <string>
#include <WS2tcpip.h>
#include <winsock2.h> 
#pragma comment(lib, "ws2_32.lib") 
int main()
{
// ********************************************************
// Defining the variables
// ********************************************************
WSADATA win32_initialisation;
int error;
SOCKET my_socket;
SOCKADDR_IN destination_information;
std::string server_IP_Addr = "192.168.0.102";
...
std::cout << "Hello, it's the client talking heren";
// ********************************************************
// Winsock  Initialisation
// ********************************************************
error = WSAStartup(MAKEWORD(2, 2), &win32_initialisation);
if (error != 0) {
std::cerr << "Sorry, can't initialize Winsock due to error : " << error << "! Quitting...n";
return 1;
}
std::cout << "WSAStartup  : OKn";
// ********************************************************
// Opening Socket
// ********************************************************
my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (my_socket == INVALID_SOCKET) {
error = WSAGetLastError();
std::cerr << "Sorry, can't create the socket due to error : " << error << "! Quitting...n";
WSACleanup();
return 1;
}
std::cout << "socket      : OKn";
// ********************************************************
// Establishing session opening
// ********************************************************
memset(&destination_information, 0, sizeof(destination_information));
destination_information.sin_family = AF_INET;
inet_pton(AF_INET, server_IP_Addr.c_str(), &destination_information.sin_addr);
destination_information.sin_port = htons(4024);
error = connect(my_socket, (sockaddr*)&destination_information, sizeof(destination_information));
if (error == SOCKET_ERROR) {
error = WSAGetLastError();
std::cerr << "Sorry, couldn't open the TCP session due to error : " << error << "! Quitting...n";
closesocket(my_socket);
WSACleanup();
return 1;
}
std::cout << "connect  : OKn";
...
}