Kreiram 2 thread-a koja pozivaju funkciju sendMessage i dobijaju odgovor sa servera. Problem nastaje kada pokrenem oba thread-a (funkcije feedCommunicationThread i loginCommunicationThread) i u FOR petlju ubacim sleep(N) ili usleep(N), dobijam grešku "ERROR reading from socket" (195. linija) sa error kodom -1.
Moja prva pretpostavka je da sleep utiče i na glavni thread a ne samo na running, ali nisam siguran jer nemam puno iskustva sa thread-ovima u C-u. Kada sklonim sleep(), prodje lepo kroz FOR petlju do kraja.
Drugo što bih hteo da pitam je - hoću da imam jedan otvoren socket sve vreme (a ne da ga otvaram i zatvaram pri svakom pozivu unutar sendMessage funkcije). Medjutim, kada taj deo koda izmestim u main() funkciju dobijam grešku pri drugom pokušaju da pošalje poruku (prvi prodje ok). Jel zna neko šta je ovde problem? Mogu da pošaljem i taj kod ako nekoga interesuje..
Bio bih zahvalan ako bi neko mogao da mi pomogne s ovim, jer sam se poprilično zaglavio.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
typedef struct config
{
char srv1_ip[100];
int srv1_port;
char auth[256];
char srv2_ip[100];
int srv2_port;
char feed[256];
} CONFIG;
char bfr[256];
void error(const char *msg);
void removeNewLine(char *buffer);
char *sendMessage(char* message, CONFIG config);
void *feedCommunicationThread(void *threadid);
void *loginCommunicationThread(void *threadid);
int main(int argc, char *argv[])
{
FILE *fp;
char buffer[100], buffer2[100];
char *cptr;
CONFIG config;
char *response;
int counter = 0, threadCreateCode, i;
fp = fopen("client.cfg", "r");
if (fp == NULL)
{
printf("Unable to read client.cfg");
exit(1);
}
// read config settings
printf("Reading settings:\n");
i = 0;
while (fgets(buffer, 100, fp))
{
cptr = strstr(buffer, "srv1_ip=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.srv1_ip, cptr);
}
cptr = strstr(buffer, "srv1_port=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr+=2;
config.srv1_port = atoi(cptr);
}
cptr = strstr(buffer, "auth=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.auth, cptr);
}
cptr = strstr(buffer, "srv2_ip=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.srv2_ip, cptr);
}
cptr = strstr(buffer, "srv2_port=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
config.srv2_port = atoi(cptr);
}
cptr = strstr(buffer, "feed=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.feed, cptr);
}
}
fclose(fp);
printf("======================\n");
printf("PARAMS: %s %d %s %s %d %s\n", config.srv1_ip, config.srv1_port, config.auth, config.srv2_ip, config.srv2_port, config.feed);
printf("======================\n\n");
// create threads
pthread_t threads[2];
threadCreateCode = pthread_create(&threads[0], NULL, feedCommunicationThread, (void *)&config);
if (threadCreateCode)
printf("ERROR: Unable to create FEED thread. Return code: %d", threadCreateCode);
threadCreateCode = pthread_create(&threads[1], NULL, loginCommunicationThread, (void *)&config);
if (threadCreateCode)
printf("ERROR: Unable to create LOGIN communication thread. Return code: %d", threadCreateCode);
pthread_exit(NULL);
/*for (i=0; i<300; i++)
{
printf("\nSending generated message.\n");
response = sendMessage("Generated message.", config);
printf("Response: %s\n\n", response);
if (strcmp(response, "OK") != 0)
counter++;
//sleep(1);
}*/
printf("Successfully executed.");
if (counter > 0)
printf("\nUnsuccessfully sent: %d/300", counter);
return 0;
}
void error(const char *msg)
{
perror(msg);
exit(0);
}
void removeNewLine(char *buffer)
{
int length = strlen(buffer)-1;
int i;
for (i=0; i<length; i++)
{
if ((int)buffer[i] == 10 || (int)buffer[i] == 13)
{
buffer[i] = '\0';
break;
}
}
}
char *sendMessage(char* message, CONFIG config)
{
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent *server;
//printf("Send message called for server %s", config.srv2_ip);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
printf("ERROR opening socket");
server = gethostbyname(config.srv1_ip);
if (server == NULL) {
printf("ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(config.srv1_port);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
printf("ERROR connecting");
bzero(bfr,256);
n = write(sockfd, message, strlen(message));
if (n < 0)
error("ERROR writing to socket");
bzero(bfr,256);
n = read(sockfd,bfr,255);
if (n < 0)
printf("ERROR reading from socket: Error code %d", n);
close(sockfd);
return &bfr[0];
}
void *feedCommunicationThread(void *cnfg)
{
//pthread_exit(NULL);
CONFIG *cfg;
cfg = (CONFIG *)cnfg;
int i;
char *r;
r = sendMessage(cfg->feed, *cfg);
if (strcmp(r, "OK") == 0)
{
// ok, go to next step
printf("FEED message successfully sent.\n");
for (i=0; i<15; i++)
{
printf("Sending ping... ");
r = sendMessage("PING...", *cfg);
if (strcmp(r, "OK") == 0)
printf("OK\n");
else
printf("NOT OK\n");
//usleep(2000);
}
}
else
{
printf("ERROR: FEED message could not be sent successfully to the server. Server responded with: %s\n", r);
}
pthread_exit(NULL);
}
void *loginCommunicationThread(void *cnfg)
{
//pthread_exit(NULL);
CONFIG *cfg;
cfg = (CONFIG *)cnfg;
char *r;
int i;
printf("AUTH: %s\n", cfg->auth);
r = sendMessage(cfg->auth, *cfg);
if (strcmp(r, "OK") == 0)
{
printf("Client successfully authenticated.\n");
for (i=0; i<10; i++)
{
sendMessage("Sending message from LOGIN function.", *cfg);
//sleep(1);
}
}
else
{
printf("AUTHENTICATION RESPONSE NOT OK: %s\n", r);
printf("Client exited with error.\n");
}
pthread_exit(NULL);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
typedef struct config
{
char srv1_ip[100];
int srv1_port;
char auth[256];
char srv2_ip[100];
int srv2_port;
char feed[256];
} CONFIG;
char bfr[256];
void error(const char *msg);
void removeNewLine(char *buffer);
char *sendMessage(char* message, CONFIG config);
void *feedCommunicationThread(void *threadid);
void *loginCommunicationThread(void *threadid);
int main(int argc, char *argv[])
{
FILE *fp;
char buffer[100], buffer2[100];
char *cptr;
CONFIG config;
char *response;
int counter = 0, threadCreateCode, i;
fp = fopen("client.cfg", "r");
if (fp == NULL)
{
printf("Unable to read client.cfg");
exit(1);
}
// read config settings
printf("Reading settings:\n");
i = 0;
while (fgets(buffer, 100, fp))
{
cptr = strstr(buffer, "srv1_ip=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.srv1_ip, cptr);
}
cptr = strstr(buffer, "srv1_port=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr+=2;
config.srv1_port = atoi(cptr);
}
cptr = strstr(buffer, "auth=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.auth, cptr);
}
cptr = strstr(buffer, "srv2_ip=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.srv2_ip, cptr);
}
cptr = strstr(buffer, "srv2_port=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
config.srv2_port = atoi(cptr);
}
cptr = strstr(buffer, "feed=");
if (cptr != NULL)
{
cptr = strstr(buffer, "=") - 1;
cptr += 2;
removeNewLine(cptr);
strcpy(config.feed, cptr);
}
}
fclose(fp);
printf("======================\n");
printf("PARAMS: %s %d %s %s %d %s\n", config.srv1_ip, config.srv1_port, config.auth, config.srv2_ip, config.srv2_port, config.feed);
printf("======================\n\n");
// create threads
pthread_t threads[2];
threadCreateCode = pthread_create(&threads[0], NULL, feedCommunicationThread, (void *)&config);
if (threadCreateCode)
printf("ERROR: Unable to create FEED thread. Return code: %d", threadCreateCode);
threadCreateCode = pthread_create(&threads[1], NULL, loginCommunicationThread, (void *)&config);
if (threadCreateCode)
printf("ERROR: Unable to create LOGIN communication thread. Return code: %d", threadCreateCode);
pthread_exit(NULL);
/*for (i=0; i<300; i++)
{
printf("\nSending generated message.\n");
response = sendMessage("Generated message.", config);
printf("Response: %s\n\n", response);
if (strcmp(response, "OK") != 0)
counter++;
//sleep(1);
}*/
printf("Successfully executed.");
if (counter > 0)
printf("\nUnsuccessfully sent: %d/300", counter);
return 0;
}
void error(const char *msg)
{
perror(msg);
exit(0);
}
void removeNewLine(char *buffer)
{
int length = strlen(buffer)-1;
int i;
for (i=0; i<length; i++)
{
if ((int)buffer[i] == 10 || (int)buffer[i] == 13)
{
buffer[i] = '\0';
break;
}
}
}
char *sendMessage(char* message, CONFIG config)
{
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent *server;
//printf("Send message called for server %s", config.srv2_ip);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
printf("ERROR opening socket");
server = gethostbyname(config.srv1_ip);
if (server == NULL) {
printf("ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(config.srv1_port);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
printf("ERROR connecting");
bzero(bfr,256);
n = write(sockfd, message, strlen(message));
if (n < 0)
error("ERROR writing to socket");
bzero(bfr,256);
n = read(sockfd,bfr,255);
if (n < 0)
printf("ERROR reading from socket: Error code %d", n);
close(sockfd);
return &bfr[0];
}
void *feedCommunicationThread(void *cnfg)
{
//pthread_exit(NULL);
CONFIG *cfg;
cfg = (CONFIG *)cnfg;
int i;
char *r;
r = sendMessage(cfg->feed, *cfg);
if (strcmp(r, "OK") == 0)
{
// ok, go to next step
printf("FEED message successfully sent.\n");
for (i=0; i<15; i++)
{
printf("Sending ping... ");
r = sendMessage("PING...", *cfg);
if (strcmp(r, "OK") == 0)
printf("OK\n");
else
printf("NOT OK\n");
//usleep(2000);
}
}
else
{
printf("ERROR: FEED message could not be sent successfully to the server. Server responded with: %s\n", r);
}
pthread_exit(NULL);
}
void *loginCommunicationThread(void *cnfg)
{
//pthread_exit(NULL);
CONFIG *cfg;
cfg = (CONFIG *)cnfg;
char *r;
int i;
printf("AUTH: %s\n", cfg->auth);
r = sendMessage(cfg->auth, *cfg);
if (strcmp(r, "OK") == 0)
{
printf("Client successfully authenticated.\n");
for (i=0; i<10; i++)
{
sendMessage("Sending message from LOGIN function.", *cfg);
//sleep(1);
}
}
else
{
printf("AUTHENTICATION RESPONSE NOT OK: %s\n", r);
printf("Client exited with error.\n");
}
pthread_exit(NULL);
}
Winners never quit, quitters never win.