我尝试使客户端发送消息的应用程序和服务器使用Winsock TCP c ++在同一台计算机上响应的应用程序。问题是服务器等待客户端连接后,我运行了客户端代码,并在连接处退出并退出。这是我的代码。
服务器:
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>
#define MY_PORT 8888
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//Init Winsock
WSADATA SData;
if (WSAStartup(0x0202, &SData) != 0)
{
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
//Init Socket
int listeningSocket;
if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket failed");
WSACleanup();
exit(EXIT_FAILURE);
}
//Set IP and PORT
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MY_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//Bind
if (bind(listeningSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("bind failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Listen
if (listen(listeningSocket, 5) < 0)
{
perror("listen failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Accept
int new_socket;
sockaddr_in client_addr;
int nSizeAddr = sizeof(sockaddr);
if (new_socket = accept(listeningSocket, (struct sockaddr *)&client_addr, &nSizeAddr) < 0)
{
perror("accept failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
while (1)
{
//recv
char buff[100];
if (recv(new_socket, buff, 100, 0) < 0)
{
perror("recv failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
cout << buff << endl;
//send
string sndStr = "Da nhan";
if (send(new_socket, sndStr.c_str(), sndStr.size(), 0) < 0)
{
perror("send failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
}
//close socket
closesocket(new_socket);
//Cleanup winsock
WSACleanup();
return 0;
}
客户:
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>
#include <string>
#define MY_PORT 8888
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//Init winsock
WSADATA SData;
if (WSAStartup(0x0202, &SData) != 0)
{
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
//Init socket
int clientSocket;
if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
{
perror("socket failed");
WSACleanup();
exit(EXIT_FAILURE);
}
//Set IP and PORT
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MY_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may
//Connect
if (connect(clientSocket, (SOCKADDR*)&server_addr, sizeof(server_addr)) < 0)
{
perror("connect failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
while (1)
{
//Send
string sndStr;
getline(cin, sndStr);
if (send(clientSocket, sndStr.c_str(), sndStr.size(), 0) < 0)
{
perror("send failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Recv
char buff[100];
if (recv(clientSocket, buff, 100, 0) < 0)
{
perror("recv failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
cout << buff << endl;
}
//Close socket
closesocket(clientSocket);
//Cleanup Winsock
WSACleanup();
}
在接受步骤中出现错误,但我不知道错误名称是什么。我该如何解决?
client_socket
的值为INVALID_SOCKET
。
答案 0 :(得分:-1)
如果出现错误,则应使用GetLastError()函数获取错误代码,每个syscall都可以报告不同的错误集,您可以在MS网站上检查错误代码的定义。
答案 1 :(得分:-1)
编辑:发现了新问题-我仍然不相信使用INADDR_ANY
作为客户地址是好的,但这实际上并不是这里的问题。
问题出在那一行:
if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
请注意,<
的优先级高于=
,因此您可以在此处为clientSocket
分配布尔值。服务器代码中的类似行添加了括号,使其可以正常工作。
服务器代码中的工作行:
if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
。
这是您的问题在这里(在客户端):
server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may
套接字的工作方式是,您创建一个服务器套接字来侦听传入的连接,并在创建时告诉它接受谁的连接。可以是来自特定地址,一定范围的地址,也可以是任何人。第三种选择是这里最常见的选择,也是您在服务器中选择的一种(绑定到INADDR_ANY)。
这部分很好。
但是,当客户端必须连接到服务器时,您不能只说:“连接到任何东西!”并期望它找到您的服务器(或任何其他东西)。因此,当您尝试连接客户端套接字时,必须为其提供服务器的实际地址。
我找到了一个执行此操作的示例:
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr)) < 0)
如果localhost
(127.0.0.1
)对您不起作用,请将地址更改为适合您服务器的地址。