服务器未启动时无法与服务器建立重复 SOCK_STREAM 连接?
Fail to make repeated SOCK_STREAM connection to the server while the server did not start?
我正在使用套接字进行网络编程。当服务器 未启动 (项目的特殊要求)时,我的客户端程序试图重复连接到服务器时出现问题。
这是问题:
服务器未启动: 客户端等待 3 秒,然后发出另一个 connect() 请求。
当我启动服务器时:客户端仍然每 3 秒尝试连接一次。
我们运行客户端程序时的错误信息:
$./client localhost
Cannot connect to the server. Retrying...: Connection refused
Cannot connect to the server. Retrying...: Invalid argument
Cannot connect to the server. Retrying...: Invalid argument
...
这是客户端代码:
#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#define SERVER_PORT "9734"
#define WAIT_SERVER_TIME 3
int main(int argc, char* argv[]){
if(argc<2){
printf("usage: %s MACHINE_NAME\n",argv[0]);
exit(EXIT_SUCCESS);
}else{
int client_socket_fd = 0 ;
struct addrinfo hints,*results;
/* Get the address info of the server to be connected */
memset(&hints,0,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if( getaddrinfo(argv[1],SERVER_PORT,&hints,&results) !=0){
printf("Cannot recognize the given server name");
exit(EXIT_FAILURE);
}
/* Create the client socket */
if((client_socket_fd = socket( AF_INET, SOCK_STREAM, 0))<0){
perror("Cannot create the client socket.");
exit(EXIT_FAILURE);
}
if(results->ai_addr == NULL){
perror("Cannot find the given server name.");
exit(EXIT_FAILURE);
}
/* Set up the connection */
while(connect(client_socket_fd,results->ai_addr,
results->ai_addrlen) < 0 ){
perror("Cannot connect to the server. Retrying...");
sleep(WAIT_SERVER_TIME);
}
printf("Successfully connected to the server.\n");
// DO STUFFS HERE
exit(EXIT_SUCCESS);
}
}
这是用于测试目的的服务器代码:
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <ifaddrs.h>
int main(int argc, char* argv[]){
/* SERVER SET UP */
int enable_reuse_socket = 1;
struct sockaddr_in server_address;
socklen_t server_address_len=0;
int server_socket_fd ;
server_socket_fd = socket( AF_INET, SOCK_STREAM, 0);
// Handle error creating a socket
if( server_socket_fd < 0){
perror("Cannot initialize the socket for connection.");
exit( EXIT_FAILURE);
}
// Set up the INET address
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr= htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_PORT);
server_address_len = sizeof( server_address);
// Bind the socket to the given address
if(setsockopt(server_socket_fd,SOL_SOCKET,SO_REUSEADDR,&enable_reuse_socket
,sizeof(int))<0){
perror("Fail to reuse socket.");
}
if(bind(server_socket_fd,(struct sockaddr*) &server_address,
server_address_len) !=0){
perror("Cannot bind the socket to the given address.");
exit(EXIT_FAILURE);
}
// Allow the socket to listen to the clients
if(listen(server_socket_fd, MAX_CLIENT)!=0){
perror("Cannot allow the socket to listen to incoming client \
messages");
exit(EXIT_FAILURE);
}
struct sockaddr_in client_addr;
socklen_t client_addr_len;
while(1){
int client_fd = accept(server_socket_fd,(struct sockaddr*)&client_addr,
&client_addr_len);
printf("Gotcha!");
}
}
一些套接字实现在失败后使套接字处于不一致状态 connect()
。尝试这样的事情:
int client_socket_fd = 0 ;
struct addrinfo hints,*results;
/* Get the address info of the server to be connected */
memset(&hints,0,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if( getaddrinfo(argv[1],SERVER_PORT,&hints,&results) !=0){
printf("Cannot recognize the given server name");
exit(EXIT_FAILURE);
}
if(results->ai_addr == NULL){
perror("Cannot find the given server name.");
exit(EXIT_FAILURE);
}
/* Set up the connection */
while(1) {
/* Create the client socket */
if((client_socket_fd = socket( AF_INET, SOCK_STREAM, 0))<0){
perror("Cannot create the client socket.");
exit(EXIT_FAILURE);
}
if (connect(client_socket_fd,results->ai_addr,
results->ai_addrlen) == 0 ) {
break;
}
perror("Cannot connect to the server. Retrying...\n");
close(client_socket_fd);
sleep(WAIT_SERVER_TIME);
}
printf("Successfully connected to the server.\n");
您也可以让您的客户喜欢以下内容。这不是使用 getaddrinfo()。
#include"sock_header.h"
#include<string.h>
#define MAXLEN 20
#define SERVER_PORT "9734"
#define WAIT_SERVER_TIME 3
int main(int argc, char **argv)
{
struct sockaddr_in server_sock;
int ret, sockfd;
int connect_failed = 1;
while(connect_failed == 1)
{
if((sockfd = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
return -1;
}
bzero(&server_sock, sizeof(server_sock));
server_sock.sin_family = AF_INET;
server_sock.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET, argv[1], &server_sock.sin_addr);
if(Connect(sockfd, (struct sockaddr *)& server_sock, sizeof(server_sock)) == -1)
{
Close(sockfd);
goto close_sock;
}
connect_failed = 0;
char writeline[MAXLEN];
char readline[MAXLEN];
int len ;
char * buf;
buf = (char *) malloc(sizeof(char)*strlen(argv[1]));
Writen(sockfd, buf, strlen(buf));
close_sock:
close(sockfd);
sleep(WAIT_SERVER_TIME);
}
return 0;
}
我正在使用套接字进行网络编程。当服务器 未启动 (项目的特殊要求)时,我的客户端程序试图重复连接到服务器时出现问题。
这是问题:
服务器未启动: 客户端等待 3 秒,然后发出另一个 connect() 请求。
当我启动服务器时:客户端仍然每 3 秒尝试连接一次。
我们运行客户端程序时的错误信息:
$./client localhost
Cannot connect to the server. Retrying...: Connection refused
Cannot connect to the server. Retrying...: Invalid argument
Cannot connect to the server. Retrying...: Invalid argument
...
这是客户端代码:
#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#define SERVER_PORT "9734"
#define WAIT_SERVER_TIME 3
int main(int argc, char* argv[]){
if(argc<2){
printf("usage: %s MACHINE_NAME\n",argv[0]);
exit(EXIT_SUCCESS);
}else{
int client_socket_fd = 0 ;
struct addrinfo hints,*results;
/* Get the address info of the server to be connected */
memset(&hints,0,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if( getaddrinfo(argv[1],SERVER_PORT,&hints,&results) !=0){
printf("Cannot recognize the given server name");
exit(EXIT_FAILURE);
}
/* Create the client socket */
if((client_socket_fd = socket( AF_INET, SOCK_STREAM, 0))<0){
perror("Cannot create the client socket.");
exit(EXIT_FAILURE);
}
if(results->ai_addr == NULL){
perror("Cannot find the given server name.");
exit(EXIT_FAILURE);
}
/* Set up the connection */
while(connect(client_socket_fd,results->ai_addr,
results->ai_addrlen) < 0 ){
perror("Cannot connect to the server. Retrying...");
sleep(WAIT_SERVER_TIME);
}
printf("Successfully connected to the server.\n");
// DO STUFFS HERE
exit(EXIT_SUCCESS);
}
}
这是用于测试目的的服务器代码:
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <ifaddrs.h>
int main(int argc, char* argv[]){
/* SERVER SET UP */
int enable_reuse_socket = 1;
struct sockaddr_in server_address;
socklen_t server_address_len=0;
int server_socket_fd ;
server_socket_fd = socket( AF_INET, SOCK_STREAM, 0);
// Handle error creating a socket
if( server_socket_fd < 0){
perror("Cannot initialize the socket for connection.");
exit( EXIT_FAILURE);
}
// Set up the INET address
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr= htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_PORT);
server_address_len = sizeof( server_address);
// Bind the socket to the given address
if(setsockopt(server_socket_fd,SOL_SOCKET,SO_REUSEADDR,&enable_reuse_socket
,sizeof(int))<0){
perror("Fail to reuse socket.");
}
if(bind(server_socket_fd,(struct sockaddr*) &server_address,
server_address_len) !=0){
perror("Cannot bind the socket to the given address.");
exit(EXIT_FAILURE);
}
// Allow the socket to listen to the clients
if(listen(server_socket_fd, MAX_CLIENT)!=0){
perror("Cannot allow the socket to listen to incoming client \
messages");
exit(EXIT_FAILURE);
}
struct sockaddr_in client_addr;
socklen_t client_addr_len;
while(1){
int client_fd = accept(server_socket_fd,(struct sockaddr*)&client_addr,
&client_addr_len);
printf("Gotcha!");
}
}
一些套接字实现在失败后使套接字处于不一致状态 connect()
。尝试这样的事情:
int client_socket_fd = 0 ;
struct addrinfo hints,*results;
/* Get the address info of the server to be connected */
memset(&hints,0,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if( getaddrinfo(argv[1],SERVER_PORT,&hints,&results) !=0){
printf("Cannot recognize the given server name");
exit(EXIT_FAILURE);
}
if(results->ai_addr == NULL){
perror("Cannot find the given server name.");
exit(EXIT_FAILURE);
}
/* Set up the connection */
while(1) {
/* Create the client socket */
if((client_socket_fd = socket( AF_INET, SOCK_STREAM, 0))<0){
perror("Cannot create the client socket.");
exit(EXIT_FAILURE);
}
if (connect(client_socket_fd,results->ai_addr,
results->ai_addrlen) == 0 ) {
break;
}
perror("Cannot connect to the server. Retrying...\n");
close(client_socket_fd);
sleep(WAIT_SERVER_TIME);
}
printf("Successfully connected to the server.\n");
您也可以让您的客户喜欢以下内容。这不是使用 getaddrinfo()。
#include"sock_header.h"
#include<string.h>
#define MAXLEN 20
#define SERVER_PORT "9734"
#define WAIT_SERVER_TIME 3
int main(int argc, char **argv)
{
struct sockaddr_in server_sock;
int ret, sockfd;
int connect_failed = 1;
while(connect_failed == 1)
{
if((sockfd = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
return -1;
}
bzero(&server_sock, sizeof(server_sock));
server_sock.sin_family = AF_INET;
server_sock.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET, argv[1], &server_sock.sin_addr);
if(Connect(sockfd, (struct sockaddr *)& server_sock, sizeof(server_sock)) == -1)
{
Close(sockfd);
goto close_sock;
}
connect_failed = 0;
char writeline[MAXLEN];
char readline[MAXLEN];
int len ;
char * buf;
buf = (char *) malloc(sizeof(char)*strlen(argv[1]));
Writen(sockfd, buf, strlen(buf));
close_sock:
close(sockfd);
sleep(WAIT_SERVER_TIME);
}
return 0;
}