- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在尝试实现一个类来创建和使用 TCP 连接。
(我是 c++ 的新手,所以我可能忘记了一些明显的东西,尽管我一直在认真检查我的代码)
请注意,稍后我将实现第二个类来处理新连接,因此代码的某些部分不完整/安排不当,我希望这不会打扰您理解它。
这是我的问题:
服务器和客户端似乎都工作正常(我一直在检查我的监听、绑定(bind)、连接功能:没有错误)而且我显然能够与客户端发送数据,但是当我尝试读取它时从服务器,我收到 WSA 错误 10038(这意味着我正在无效套接字上执行 recv())。我已经查了几天了,似乎找不到我的错误。除了代码中的测试之外,我还使用了“netstat -an -p tcp”来检查连接状态,一切看起来都很好,但服务器就是收不到数据。
注意:我使用的是 Visual Studio 6(是的,它很旧,但它是强制性的,所以...)和 winsock,而不是 winsock2。
如果我忘记了什么就问,我会尽量做到完整,但忘记一些事情并非不可能。
这是我的源代码,我试图将其精简到最基本的部分,但我担心错误几乎无处不在:
CmTcpTransport.cpp
/**
Initializes the TCP connection (socket) in CLIENT or SERVER mode.
It does not connect yet.
@param strIPAddress: IP Address to reach
nPort: Port to connect to
hSocket: client Socket if SERVER mode
nTcpMode: mode for this connexion SERVER(1) or CLIENT(2)
@return an int to get the exit point of the function
*/
int CmTcpTransport::initialize(std::string strIPAddress, unsigned int nPort, SOCKET hSocket, int nTcpMode)
{
m_nTcpMode = nTcpMode;
cout << "Creating TCP connexion..." << endl << endl;
if (nTcpMode == 1) // SERVER
{
serveraddr.sin_family = AF_INET; // address family Internet
serveraddr.sin_port = htons (nPort); // Port to connect on
serveraddr.sin_addr.s_addr = inet_addr (strIPAddress.c_str()); // Target IP
cout << "SERVER: Retrieving socket information..." << endl;
if (hSocket == INVALID_SOCKET)
{
return 102; // The received socket is invalid
cout << "SERVER: Socket creation failed" << endl;
}
serverSocket = hSocket;
cout << "SERVER: Listening socket received" << endl;
if (bind(serverSocket, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR)
{
return 103; // Couldn't bind
cout << "SERVER: Socket binding failed" << endl;
}
else {
cout << "SERVER: Binding successful" << endl;
}
if (listen(serverSocket, 1) == SOCKET_ERROR)
{
return 103; // Couldn't listen
cout << "SERVER: Socket listening failed" << endl;
}
else {
cout << "SERVER: Listening to socket" << endl;
}
}
else // CLIENT
{
serveraddr.sin_family = AF_INET; // address family Internet
serveraddr.sin_port = htons (nPort); // Port to connect on
serveraddr.sin_addr.s_addr = inet_addr (strIPAddress.c_str()); // Target IP
cout << "CLIENT: Creating client socket..." << endl;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // CREATE CLIENT SOCKET
if (clientSocket == INVALID_SOCKET)
{
return 104; // Couldn't create the socket
cout << "CLIENT: Socket creation failed" << endl;
}
cout << "CLIENT: Client socket created" << endl;
}
cout << "Initialization succeeded." << endl << endl << endl;
return 105;
}
/**
Creates the connexion to TCP
@param none
@return an int to get the exit point of the function
*/
int CmTcpTransport::connectTcp()
{
if (m_nTcpMode == 1) // SERVER
{
cout << "Waiting for connexion..." << endl;
int clientLen(0);
clientLen = sizeof(clientaddr);
if ((clientSocket = accept(serverSocket, (SOCKADDR *)&clientaddr, &clientLen) == INVALID_SOCKET))
{
cout << "SERVER: Connexion failed." << endl;
return 202;; // Couldn't listen
}
else {
cout << "SERVER: Connexion established." << endl << endl << endl;
if (clientSocket == SOCKET_ERROR)
{
printf("socket became invalid after connexion:: %d\n", WSAGetLastError());
}
else {
cout << "SOCKET STILL VALID AND WORKING AFTER CONNEXION" << endl;
}
return 201;
}
}
else // CLIENT
{
cout << "Connecting..." << endl;
if (connect(clientSocket, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR)
{
cout << "CLIENT: Connexion failed." << endl << endl << endl;
return 202;; // Couldn't connect
}
else
{
cout << "CLIENT: Connexion to server succeeded." << endl << endl << endl;
}
return 203;
}
}
/**
Receives a buffer of bytes from the TCP
@param buffer: buffer to store the data
bufLen: size of the buffer
@return nbChar: the result of the recv function
if no error occurs, recv returns the number of bytes received
else, it returns a value of SOCKET_ERROR
*/
int CmTcpTransport::recvTcp(char *buffer, int bufLen)
{
if (clientSocket == SOCKET_ERROR)
{
printf("socket became invalid before receive:: %d\n", WSAGetLastError());
}
else {
cout << "SOCKET STILL VALID AND WORKING BEFORE RECEIVE" << endl;
}
int nbChar = recv(clientSocket, buffer, bufLen, 0);
if (nbChar == SOCKET_ERROR)
{
printf("recv failed: %d\n", WSAGetLastError());
cout << "No data received." << endl << endl << endl;
return nbChar;
}
else {
buffer[nbChar]=0; // Gestion de la taille du buffer
cout << "Data received: " << buffer << endl << endl << endl;
return nbChar;
}
}
/**
Sends a buffer of bytes to the TCP
@param buffer: buffer containing the data
bufLen: size of the buffer
@return nbChar: the result of the send function
if no error occurs, recv returns the number of bytes sent
else, it returns a value of SOCKET_ERROR
*/
int CmTcpTransport::sendTcp(char *buffer, int bufLen)
{
int nbChar = send(clientSocket, buffer, bufLen,0);
if (nbChar == SOCKET_ERROR)
{
cout << "No data sent." << endl << endl << endl;
return nbChar;
}
else {
cout << "Data sent: " << buffer << endl << endl << endl;
return nbChar;
}
}
服务器main.cpp
int main(int argc, char* argv[])
{
// ----------------------- WINSOCK ----------------------------
cout << "Initializing winsock library..." << endl;
// Start up Winsock
WSADATA wsadata;
int error = WSAStartup(0x101, &wsadata);
// Error ?
if (error) 0;
// Try Winsock Version ?
if (wsadata.wVersion != 0x101)
{
WSACleanup(); // Clean up Winsock
return 101;
}
cout << "Initialization successful" << endl << endl << endl;
// ----------------------- SERVER ---------------------------
char buffer[3000];
int testRecv; // return of the recv function
cout << "SERVER" << endl << endl << endl;
// Simulate the activity of the TcpListener transfering a listening Socket for the client connexion
SOCKET testSocket;
testSocket = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
// Creating a new TCP transport
CmTcpTransport server;
// Initialize and connect the TCP transport
server.initialize("127.0.0.1", 10000, testSocket, TTCP_MODE_SERVER);
server.connectTcp();
// Try to receive data
testRecv = server.recvTcp(buffer, sizeof(buffer));
cout << testRecv << endl;
// Disconnect
server.disconnectTcp();
return 0;
}
客户端main.cpp
int main(int argc, char* argv[])
{
// ----------------------- WINSOCK ----------------------------
cout << "Initializing winsock library..." << endl;
// Start up Winsock
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
// Error ?
if (error) 0;
// Try Winsock Version ?
if (wsadata.wVersion != 0x0202)
{
WSACleanup(); // Clean up Winsock
return 101;
}
cout << "Initialization successful" << endl << endl << endl;
// ----------------------- CLIENT ---------------------------
char buffer[10000];
cout << "CLIENT" << endl << endl << endl;
// this Socket won't be used as the TCP transport is in client mode
SOCKET test;
test = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
// Create, initialize and connect the client TCP transport
CmTcpTransport client;
client.initialize("127.0.0.1", 10000, test, TTCP_MODE_CLIENT);
client.connectTcp();
// Copy the data in the buffer and send it
strcpy(buffer, "Test donnees");
client.sendTcp(buffer, sizeof(buffer));
client.disconnectTcp();
return 0;
}
下面是我运行两个主电源时我的控制台的屏幕截图:
http://www.hostingpics.net/viewer.php?id=892752Consoles.jpg
感谢您的帮助,我意识到需要阅读/处理的内容很多,感谢您的努力!
最佳答案
我认为你在 accept
上用不正确的大括号使新的 sock-id 无效:
if ((clientSocket = accept(serverSocket, (SOCKADDR *)&clientaddr, &clientLen) == INVALID_SOCKET))
尝试将其更改为:
if ((clientSocket = accept(serverSocket, (SOCKADDR *)&clientaddr, &clientLen)) == INVALID_SOCKET)
关于c++ - 在我的代码中出现这个 "10038 wsa socket"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30028754/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!