基于 UNIX 套接字的客户端程序中的 C++ connect() 不建立与服务器的连接
C++ connect() in UNIX-socket based client program does not establish a connection to the server
我使用著名的 Berkeley 套接字接口在 CentOS 7.0 中用 C++ 编写了一个简单的套接字服务器。我 运行 它,在任何端口上,它等待连接。
然后我 运行 我的简单客户端程序也是用 c++ 编写的,并向
192.168.122.1
(这个IP是通过执行命令ip addr
找到的)但是拒绝连接。由于担心防火墙,我停止了 httpd.service (APACHE) 并在端口 80 上执行了该过程,但无济于事,我收到错误 "Connection Refused".
我该怎么办?
** 更新 001 **
当我 运行 命令 netstat -l
我得到以下输出:
.
.
tcp 0 0 0.0.0.0:9005 0.0.0.0:* LISTEN
.
.
** 更新 001 结束 **
以下是输出:
客户端 --> 拒绝连接
服务器 --> [等待...]
代码如下:
客户:
#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
namespace TCP {
class Client {
public :
static bool Connect(int argc, char *argv[]) {
int returnStatus = 0;
char* buffer[256];
if (3 != argc) {
// warn that the port MUST be specified.
fprintf(stderr, "Incorrect parameter for port and server's address. Usage: %d <port>.\n", argv[0]);
exit(1); // shut down the application
}
// streaming socket is the same as server's one.
// Note: we use TCP Streaming and not UDP's datagram.
int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//
struct sockaddr_in serverObject;
short int portNumber = atoi(argv[1]);
/**
* We use memset() of cstring header
* to set all uninitialized values of
* the struct serverObject to zero.
*/
memset(&serverObject,
0, sizeof(serverObject));
// now set the values properly
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.s_addr = inet_addr(argv[2]);
serverObject.
sin_port = htons(portNumber);
// we need now to connect to the server by porting out
// out socketObject
returnStatus = connect(socketObject, (sockaddr *)&serverObject, sizeof(serverObject));
if (returnStatus == 0) {
fprintf(stdout, "Connect successfully done.");
}
else {
fprintf(stderr, "Connection failed! Error %s\n", strerror(errno));
close(socketObject);
exit(errno);
}
// now it's time to read the data from the server by using read()
// we read it up to the point of our buffer size
returnStatus = read(socketObject, buffer, sizeof(buffer));
if (returnStatus == -1) {
fprintf(stderr, "cannot read the data.");
close(socketObject);
exit(1);
}
else if( returnStatus > 0)
{
cout << buffer << endl;
close(socketObject);
}
}
};
}// end of namespaCE
服务器
#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <unistd.h>
using namespace std;
const char DATA_BACK_TO_CLIENT[] = "A simple socket server!";
namespace TCP {
class Server {
public :
static bool Connect(int argc, char *argv[]) {
int returnStatus = 0;
if (2 != argc) {
// warn that the port MUST be specified.
fprintf(stderr, "Incorrect parameter for port. Usage: %d <port>.\n", argv[0]);
exit(1); // shut down the application
}
int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serverObject;
int portNumber = atoi(argv[1]);
/**
* We use memset() of cstring header
* to set all uninitialized values of
* the struct serverObject to zero.
*/
memset(&serverObject,
0, sizeof(serverObject));
// now set the values properly
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.
s_addr = htonl(INADDR_ANY);
serverObject.
sin_port = htonl(portNumber);
returnStatus = bind(socketObject, (struct sockaddr *) &serverObject,
sizeof(serverObject));
if (returnStatus != 0) {
fprintf(stderr, "Cannot do the binding. Socket closed.");
close(socketObject);
exit(1);
}
returnStatus = listen(socketObject, 5); // 5 is a typical value for backlog
// which denotes the number of allowed connections in queue, After linux 2.2,
// only completed connections are counted in the queue.
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on the socketl.");
close(socketObject);
exit(1);
}
while (1) {
cout << "Server has started successfully. Info:" << endl;
cout << "Port Number Listening to: " << portNumber << endl;
int simpleChildSocket = 0;
struct sockaddr clientSocket = {0};
int simpleClient = 0;
socklen_t clientNameLength = sizeof(clientSocket);
cout << "Listening Status:" << returnStatus << endl;
/** blocking-state. accept() is a blocking
* function essentially.
* **/
simpleChildSocket = accept(socketObject, &clientSocket,
&clientNameLength);
cout << "Accept Connection Status: " << simpleChildSocket << endl;
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connectios.\n");
close(socketObject);
exit(1);
}
/**
* Handle the incoming request
* write received data from the server
*/
write(simpleChildSocket, DATA_BACK_TO_CLIENT, sizeof(DATA_BACK_TO_CLIENT));
// closing the child socket
close(simpleChildSocket);
}
close(socketObject);
}
};
}// end of namespaCE
端口号需要设置为htons(),
而不是htonl().
我使用著名的 Berkeley 套接字接口在 CentOS 7.0 中用 C++ 编写了一个简单的套接字服务器。我 运行 它,在任何端口上,它等待连接。
然后我 运行 我的简单客户端程序也是用 c++ 编写的,并向
192.168.122.1
(这个IP是通过执行命令ip addr
找到的)但是拒绝连接。由于担心防火墙,我停止了 httpd.service (APACHE) 并在端口 80 上执行了该过程,但无济于事,我收到错误 "Connection Refused".
我该怎么办?
** 更新 001 **
当我 运行 命令 netstat -l
我得到以下输出:
.
.
tcp 0 0 0.0.0.0:9005 0.0.0.0:* LISTEN
.
.
** 更新 001 结束 ** 以下是输出:
客户端 --> 拒绝连接
服务器 --> [等待...]
代码如下:
客户:
#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
namespace TCP {
class Client {
public :
static bool Connect(int argc, char *argv[]) {
int returnStatus = 0;
char* buffer[256];
if (3 != argc) {
// warn that the port MUST be specified.
fprintf(stderr, "Incorrect parameter for port and server's address. Usage: %d <port>.\n", argv[0]);
exit(1); // shut down the application
}
// streaming socket is the same as server's one.
// Note: we use TCP Streaming and not UDP's datagram.
int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//
struct sockaddr_in serverObject;
short int portNumber = atoi(argv[1]);
/**
* We use memset() of cstring header
* to set all uninitialized values of
* the struct serverObject to zero.
*/
memset(&serverObject,
0, sizeof(serverObject));
// now set the values properly
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.s_addr = inet_addr(argv[2]);
serverObject.
sin_port = htons(portNumber);
// we need now to connect to the server by porting out
// out socketObject
returnStatus = connect(socketObject, (sockaddr *)&serverObject, sizeof(serverObject));
if (returnStatus == 0) {
fprintf(stdout, "Connect successfully done.");
}
else {
fprintf(stderr, "Connection failed! Error %s\n", strerror(errno));
close(socketObject);
exit(errno);
}
// now it's time to read the data from the server by using read()
// we read it up to the point of our buffer size
returnStatus = read(socketObject, buffer, sizeof(buffer));
if (returnStatus == -1) {
fprintf(stderr, "cannot read the data.");
close(socketObject);
exit(1);
}
else if( returnStatus > 0)
{
cout << buffer << endl;
close(socketObject);
}
}
};
}// end of namespaCE
服务器
#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <unistd.h>
using namespace std;
const char DATA_BACK_TO_CLIENT[] = "A simple socket server!";
namespace TCP {
class Server {
public :
static bool Connect(int argc, char *argv[]) {
int returnStatus = 0;
if (2 != argc) {
// warn that the port MUST be specified.
fprintf(stderr, "Incorrect parameter for port. Usage: %d <port>.\n", argv[0]);
exit(1); // shut down the application
}
int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serverObject;
int portNumber = atoi(argv[1]);
/**
* We use memset() of cstring header
* to set all uninitialized values of
* the struct serverObject to zero.
*/
memset(&serverObject,
0, sizeof(serverObject));
// now set the values properly
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.
s_addr = htonl(INADDR_ANY);
serverObject.
sin_port = htonl(portNumber);
returnStatus = bind(socketObject, (struct sockaddr *) &serverObject,
sizeof(serverObject));
if (returnStatus != 0) {
fprintf(stderr, "Cannot do the binding. Socket closed.");
close(socketObject);
exit(1);
}
returnStatus = listen(socketObject, 5); // 5 is a typical value for backlog
// which denotes the number of allowed connections in queue, After linux 2.2,
// only completed connections are counted in the queue.
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on the socketl.");
close(socketObject);
exit(1);
}
while (1) {
cout << "Server has started successfully. Info:" << endl;
cout << "Port Number Listening to: " << portNumber << endl;
int simpleChildSocket = 0;
struct sockaddr clientSocket = {0};
int simpleClient = 0;
socklen_t clientNameLength = sizeof(clientSocket);
cout << "Listening Status:" << returnStatus << endl;
/** blocking-state. accept() is a blocking
* function essentially.
* **/
simpleChildSocket = accept(socketObject, &clientSocket,
&clientNameLength);
cout << "Accept Connection Status: " << simpleChildSocket << endl;
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connectios.\n");
close(socketObject);
exit(1);
}
/**
* Handle the incoming request
* write received data from the server
*/
write(simpleChildSocket, DATA_BACK_TO_CLIENT, sizeof(DATA_BACK_TO_CLIENT));
// closing the child socket
close(simpleChildSocket);
}
close(socketObject);
}
};
}// end of namespaCE
端口号需要设置为htons(),
而不是htonl().