如何解决在C ++中使用TCP套接字进行远程客户端和服务器通信
我想使用套接字编程远程运行服务器和客户端(我的PC上的客户端和远程主机上的服务器)。我已经用C ++编写了一个程序,该程序可以在客户端和服务器的本地计算机上运行。现在如何从其他计算机上运行服务器?在server.cpp中,我使用了INADDR_ANY,我不知道如何将我的PC(正在运行该服务器的IP)的IP地址提供给客户端,以及该PC的ip地址(我在其上有我的客户端程序) )到服务器。客户端和服务器是否具有相同的端口号,或者它们也可以具有不同的端口号?如果是,那我该如何分配?
server.cpp
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#include <cstdlib>
#pragma comment (lib,"ws2_32.lib")
using namespace std;
void main()
{
WSADATA data;
WORD ver = MAKEWORD(2,2);
int wres = WSAStartup(ver,&data);
if (wres != 0)
{
cerr << "unable to initialize winsock" << endl;
return;
}
SOCKET listening = socket(AF_INET,SOCK_STREAM,0);
if (listening == INVALID_SOCKET)
{
cerr << "unable to create a socket" << endl;
return;
}
sockaddr_in sdata;
sdata.sin_family = AF_INET;
sdata.sin_port = htons(54000);
sdata.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening,(sockaddr*)&sdata,sizeof(sdata));
listen(listening,SOMAXCONN);
sockaddr_in client;
int csize = sizeof(client);
SOCKET clientsock = accept(listening,(sockaddr*)&client,&csize);
char host[NI_MAXHOST];
char service[NI_MAXSERV];
ZeroMemory(host,NI_MAXHOST);
ZeroMemory(service,NI_MAXSERV);
if (getnameinfo((sockaddr*)&client,sizeof(client),host,NI_MAXHOST,service,NI_MAXSERV,0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET,&client.sin_addr,NI_MAXHOST);
cout << host << " connected on port " <<
ntohs(client.sin_port) << endl;
}
//listening
closesocket(listening);
char buf[4096];
//char temp[] = "Hello";
//char *input = temp;
string input;
int inputsize;
while (true)
{
ZeroMemory(buf,4096);
int recbyte = recv(clientsock,buf,4096,0);
if (recbyte == SOCKET_ERROR)
{
cerr << "Error in recv(). Quitting" << endl;
break;
}
if (recbyte == 0)
{
cout << "Client disconnected " << endl;
break;
}
cout << "Client>";
cout << string(buf,recbyte) << endl;
cout << "> ";
getline(cin,input);
send(clientsock,input.c_str(),input.size() + 1,0);
}
closesocket(clientsock);
WSACleanup();
system("pause");
}
client.cpp
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void main()
{
string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2,2);
int wsResult = WSAStartup(ver,&data);
if (wsResult != 0)
{
cerr << "Can't start Winsock,Err #" << wsResult << endl;
return;
}
SOCKET sock = socket(AF_INET,0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket,Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET,ipAddress.c_str(),&hint.sin_addr);
int connResult = connect(sock,(sockaddr*)&hint,sizeof(hint));
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server,Err #" << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
string userInput;
do
{
cout << "> ";
getline(cin,userInput);
if (userInput.size() > 0)
{
int sendResult = send(sock,userInput.c_str(),userInput.size() + 1,0);
if (sendResult != SOCKET_ERROR)
{
ZeroMemory(buf,4096);
int bytesReceived = recv(sock,0);
if (bytesReceived > 0)
{
cout << "SERVER> " << string(buf,bytesReceived) << endl;
}
}
}
} while (userInput.size() > 0);
closesocket(sock);
WSACleanup();
}
解决方法
我认为您不完全了解客户端服务器角色。 服务器不但不能也不应该知道连接到它的客户端的地址(尽管在连接后它可以知道)。 为了完成连接,客户端需要知道他们应该连接到的IP和PORT,并且服务器应该将其服务器端口(侦听它的端口)绑定到正确的IP和PORT。 通常使用INADDR_ANY来描述默认IP,在大多数情况下都可以,但是如果计算机上有多个地址,则可能必须指定另一个地址。 客户端通常不绑定其连接套接字,因为它们自己的端口号并不重要。同样,他们自己的IP也不重要,因为在连接过程中不会使用它。 因此,您应该做的是在PC上运行服务器应用程序,并将PC的地址和PORT端口号提供给所有寻求与您连接的客户端。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。