【发布时间】:2015-12-29 11:48:09
【问题描述】:
我一直能够找到一种方法来修复我的代码,只是调试和浏览网页,但我现在卡在一些代码上,我看不出我可以做什么样的测试来调试它。
基本上我正在尝试在 C++ 中实现一个简单的客户端/服务器关系,我评论了每一行以确保我理解我在做什么,但它仍然不起作用。
这是我的客户代码:
void startClient(){
int wsaStatus, connectStatus; //check errors
WSADATA WSAData;
wsaStatus=WSAStartup(MAKEWORD(2, 0), &WSAData);
if (wsaStatus != NO_ERROR) {
std::cout << "WSA Startup failed with error : " << wsaStatus;
}
SOCKET sock; //defines the sockets TO SEND
SOCKADDR_IN sin;//information about the socket
sin.sin_addr.s_addr = inet_addr("127.0.0.1");//ip of the server you want to connect to
sin.sin_family = AF_INET;//family of the socket, for internet it's AF_INET
sin.sin_port = htons(1234);// 23 for telnet etc, it's the port
sock = socket(AF_INET, SOCK_STREAM, 0);//second parameter is the type of the socket, SOCK_STREAM opens a connection ( use for TCD ), SOCK_DGRAM doesn't connect() or accept() it's used for UDP
if (sock == INVALID_SOCKET) {
std::cout << "INVALID SOCKET " << WSAGetLastError();
WSACleanup();
}
bind(sock, (SOCKADDR *)&sin, sizeof(sin)); //binds the socket to the port and the adress above
char buffer[255]; //creates a buffer to receive messages
connectStatus=connect(sock, (SOCKADDR *)&sin, sizeof(sin)); //function to connect to the server
if (connectStatus == SOCKET_ERROR) { //it returns 0 if no error occurs
std::cout << "Connection failed with error : " << WSAGetLastError();
closesocket(sock);
WSACleanup();
}
int iResult = send(sock, "Hello world!\r\n", 14, 0);
if (iResult == SOCKET_ERROR) {
std::cout << "Send failed with error : " << WSAGetLastError() << std::endl;
}
closesocket(sock);
WSACleanup();
system("pause");
这是我的服务器代码:
void startServer(){
int wsaStatus; //check errors
WSADATA WSAData;
wsaStatus=WSAStartup(MAKEWORD(2, 0), &WSAData);
if (wsaStatus != NO_ERROR) {
std::cout << "WSA Startup failed with error : " << wsaStatus;
}
SOCKET sock; //defines the sockets
SOCKADDR_IN sin; //information about the socket
sin.sin_addr.s_addr = htonl(INADDR_ANY); //since it's the server we accept any connection
sin.sin_family = AF_INET; //family of the socket, for internet it's AF_INET
sin.sin_port = htons(1234); // 23 for telnet etc, it's the port
sock = socket(AF_INET, SOCK_STREAM, 0); //second parameter is the type of the socket, SOCK_STREAM opens a connection ( use for TCD ), SOCK_DGRAM doesn't connect() or accept() it's used for UDP
if (sock == INVALID_SOCKET) {
std::cout << "INVALID SOCKET " << WSAGetLastError();
WSACleanup();
}
bind(sock, (SOCKADDR *)&sin, sizeof(sin)); //binds the socket to the port and the adress above
char buffer[255]; //to receive the messages
listen(sock, 1); //listens on the port of the socket, second parameter is the maximum of connections accepted
while (1)
{
int sizeof_sin = sizeof(sin); //size of the socket used to take the information from the client connected
sock = accept(sock, (SOCKADDR *)&sin, &sizeof_sin); //first parameter : socket, second parameter : client information socket, third parameter : size of the information about the socket
std::cout << "Connection ok" << std::endl;
if (sock != INVALID_SOCKET)
{
recv(sock, buffer, sizeof(buffer), 0);
closesocket(sock);
std::cout << buffer << std::endl;
}
else{
std::cout << "ERROR" << std::endl;
}
}
WSACleanup();
所以我首先启动服务器,它在 accept() 函数处停止等待连接,然后我启动客户端,它成功发送消息但服务器仍然在 accept() 函数处等待并且没有收到任何消息消息。
如您所见,我实施了很多错误检查,但仍然没有帮助:')
干杯!
【问题讨论】:
-
检查 bind(sock, (SOCKADDR *)&sin, sizeof(sin));返回值。是否成功。
-
如果在 linux 上,你可以打印 strerror(errno) 以获取操作系统通知的错误,但我不知道它在 windows 中是如何完成的
-
在您的服务器代码中,您正在重用您监听的同一个套接字来存储接受的结果。 Accept 创建一个全新的套接字,所以使用一个新的套接字变量。
-
另外,在客户端,不需要调用bind。套接字将在连接时隐式绑定 - 现在您正在尝试将客户端和服务器绑定到同一个端口。这不会奏效。
-
首先,谢谢大家的回答,这真的帮助我理解了。我认为这里的问题是我对套接字如何工作的理解不足! -我将在代码正常工作后立即对其进行编辑(现在客户端/服务器通信正常,但我仍有一些可以修复的错误)
标签: c++ sockets tcp server client