Witam,
Jestem w trakcie pisania prostego serwera chatu, aby nauczyć się programowania gniazd w systemach zgodnych z POSIX (nic związanego z uczelnią, by lepiej poznać C i Uniksa). W pewnym momencie spowodowałem błąd i od tej pory klient nie łączy się z serwerem. Jestem pewny, że używam właściwego portu oraz adresu IP.
Jeśli ktoś pyta po co klient na chwilę ma stać się serwerem? Po to aby serwer wysłał mu informacje trzymane w swoim kontenerze. Nastepnie zamyka serwerowe gniazdo.
Główny problem: connect call failed: Connection refused
Mam pewność, że aplikacja serwera jest aktywna w momencie, gdy klient próbuje połączyć się z serwerem.
- Dlaczego connection refused mimo że serwer nasłuchuje?
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<time.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include "msgcontainer.h"
#include "config.h"
void usage(const char* argv1) {
fprintf(stderr, "Need to create config file in user home directory: ~/.chatsrv/svr.conf\n");
fprintf(stderr, "Check ~/.chatsvr/svr.conf.default\n");
fprintf(stderr, "It is not a good idea to run this deamon as root!\n");
fprintf(stderr, "Run '%s -D' to daemonize!\n", argv1);
exit(0);
}
int main(int argc, char** argv)
{
if ( ( argc == 2 && ( strcmp(argv[1], "--help") == 0 ) ) || argc > 2 )
usage(argv[0]);
/*
* Run in background
*/
if(argc > 1 && ( strcmp(argv[1], "-D") == 0 ) ) {
printf("Going background..\n");
pid_t pid;
switch( pid = fork() ) {
case 0: // child
break;
default: // parent
printf("Background %d\n", pid);
return 0;
}
}
/*
* Config loading.
*/
init_directory();
load_config();
/*
* Container setup
*/
msgroot* root = NULL;
msglist* top = NULL;
initialize_list(&root, &top);
/*
* Run server
*/
int sockfd, newsockfd;
struct sockaddr_in server = {AF_INET, clientport, INADDR_ANY};
// set the end point of the transport
if( ( sockfd = socket(AF_INET, SOCK_STREAM, 0 )) == -1 ) {
fprintf(stderr, "Socket call failed!\n");
exit(1);
}
// bind server address with the end point
if( bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) == -1 ) {
fprintf(stderr, "Bind call failed!\n");
exit(1);
}
// listen
if( listen(sockfd, 5) == -1 ) {
fprintf(stderr, "Listen call failed!\n");
exit(1);
}
msgbody tmp;
struct sockaddr_in client;
int len = sizeof(struct sockaddr_in);
char buff[MAX_LINE];
// proceed connection
printf("Started accept loop..\n");
while(1) {
// accept for connections
if( ( newsockfd = accept(sockfd, (struct sockaddr*) &client, &len)) == -1 ) {
fprintf(stderr, "Accept call failed!\n");
continue;
}
// log connection
time_t time;
FILE* fp;
if( (fp = fopen(logpath, "a+")) == NULL ) {
fprintf(stderr, "Cannot open log file!\n");
exit(1);
}
printf("Connection from %s port %d\n", inet_ntop(AF_INET, &client.sin_addr, buff,
sizeof(buff)), ntohs(client.sin_port));
fprintf(fp, "Connection from %s port %d\n", inet_ntop(AF_INET, &client.sin_addr, buff,
sizeof(buff)), ntohs(client.sin_port));
fclose(fp);
// create child to proceed new connection
if( fork() == 0 ) {
// recieve data
while( recv(newsockfd, &tmp, sizeof(msgbody), 0) > 0 ) {
printf("Code: %d\n", tmp.code);
/*
* for code = -1 then send list of messages to the client
*/
if(tmp.code == -1) {
struct sockaddr_in client_server = {AF_INET, clientport};
// server (of client application) address
client_server.sin_addr.s_addr = client.sin_addr.s_addr;
int sendsockd;
// connect to client
if( (sendsockd = socket(AF_INET, SOCK_STREAM, 0) ) == -1 ) {
fprintf(stderr, "Socket failed\n");
exit(1);
}
// send container to client
client_server.sin_addr = client.sin_addr;
close(sendsockd);
}
if(tmp.code == 1) {
// push message to container
// while push set code = 0
tmp.code = 0;
push(root, &top, tmp);
printf("Number of elements: %d\n", size(root));
printf(ctime(&tmp.time));
printf("%s: %s", tmp.name, tmp.msg);
}
}
}
}
return 0;
}
Klient:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<time.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include "msgcontainer.h"
int main(int argc, char** argv)
{
/*
* Basic client setup
*/
/*
* Container setup
*/
msgroot* root = NULL;
// top of the list
msglist* top = NULL;
initialize_list(&root, &top);
/*
* Connect to server
*/
int sockfd, sockfdb;
const int port = 4321;
struct sockaddr_in server = {AF_INET, port};
// convert and remember server address
server.sin_addr.s_addr = inet_addr("10.0.0.5");
// set the end point of transport
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
perror("socket call failed");
exit(1);
}
// connect socket with server address
if ( connect(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) == -1 ) {
perror("connect call failed");
exit(1);
}
/*
* Recieve data from server
*/
msgbody tmp;
int clientlisten = 25000;
struct sockaddr_in tmpserver = {AF_INET, clientlisten, INADDR_ANY};
// code = -1 - get list of messages from server
tmp.code = -1;
send(sockfd, &tmp, sizeof(msgbody), 0);
if ( (sockfdb = socket(AF_INET, SOCK_STREAM, 0 )) == -1 ) {
perror("socket call failed");
exit(1);
}
if ( bind(sockfdb, (struct sockaddr*) &tmpserver, sizeof(struct sockaddr_in)) == -1 ) {
perror("bind call failed");
exit(1);
}
// there will be getting structures code
close(sockfdb);
/*
* Run client information sending.
*/
time_t currenttime;
char msgbuf[MSGSIZE];
const char* name = "Author";
while(1) {
currenttime = time(NULL);
// send information to server
printf("Message: ");
fgets(msgbuf, MSGSIZE - 1, stdin);
strcpy(tmp.msg, msgbuf);
strcpy(tmp.name, name);
tmp.time = currenttime;
// code 1 - normal message
tmp.code = 1;
send(sockfd, &tmp, sizeof(msgbody), 0);
}
close(sockfd);
return 0;
}
Raczej w tym miesjcu kończy się kod, gdzie na 95% wydaje mi się, że jest błąd.