I have 3 programs running. A client, a main server and a backup server. I want to somehow determine if the main server is up (did it crash) so that if not I can send the message to the backup. I have tried if(send(....) >= 0){....} that obviously didn't work, any other ideas?
From your client, you need to continuously try to read data from the server.
Something like this :
Incase you are using Linux based server/client.
while ( (n = read(socket_fd, recvBuffer, sizeof(recvBuffer)-1)) > 0)
{
recvBuffer[n] = 0;
if(fputs(recvBuffer, stdout) == EOF)
{
printf("\n Error : error in Fputs\n");
}
}
You can create this socket_fd using connect and passing the server address.
Related
My code, which is written in C for the C Client binding for zookeeper, runs perfectly on my local computer using the same ip (not localhost:2181). However, compiling and executing my code on another computer yields with a connection loss error. I was not able to connect to my zookeeper server by using my public IP(I got my publicIP by looking up whatsmyip on google). I did an ifconfig on my terminal to get the 10.111.129.199. I am assuming this is a private IP as it starts with 10. The machine I have ssh'd to is running SolarisOS. This caused me to change a single function in zookeeper source code from synch_fetch_and_add (I think) to atomic_add because sync_fetch... is not supported by SolarisOS. According to ZooKeeper documentation, SolarisOS is not currently supported by Zookeeper. I am able to compile Zookeeper perfectly fine, and am told someone else in my company had implemented Zookeeper beforehand on our systems.
My program is trying to create a single node on the zookeeper server. My code looks like this:
int main(int argc, char *argv[]){
//zh is a global zookeeper_handle for now.
zh = zookeeper_init(host_port, my_watcher_func, 20000, 0, NULL, 0);
if(zh == NULL){
fprintf(stderr, "Error connecting to ZooKeeper Server!! \n");
exit(EXIT_FAILURE);
return 0;
}
int retval = create("/TFS/pool" , "1");
printf("return value of create = %d\n", retval);
}
int create(char* path, char* data){
int value_length= -1;
if(data != NULL){
value_length = (int) strlen(data);
}
printf("creating node at path: %s with data %s\n", path, data);
int retval = zoo_create( zh, path, data, value_length,
&ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
return retval;
}
/*empty watcher function*/
//I have no idea why this is needed.
void my_watcher_func(zhandle_t *zzh, int type, int state,
const char *path, void *watcherCtx) {}
Both systems are running GCC compiler. The problem, I think, isn't in the code as it runs fine locally, but the connection issue I am facing.
I would assume that zh would return 0 if the connection to the zookeeper was a failure from the zookeeper_init() function. This however does not happen and continues to the create().
creating node at path: /TFS/pool with data abc
2018-07-16
10:30:44,232:16332(0x2):ZOO_ERROR#handle_socket_error_msg#1670: Socket
[10.111.129.190:2181] zk retcode=-4, errno=0(Error 0): connect() call
failed
return value of create = -4
When I telnet to the ip:port it will connect. I also know that zookeeper detects my connection during telnet because I am running it in the foreground. The following is the output of zkServer.sh running in foreground when I connect via telnet 10.111.129.190 2181
2018-07-16 11:04:03,807 [myid:] - INFO
[NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory#215] -
Accepted socket connection from /10.7.1.70:61479
The expected output should have been:
creating node at path: /TFS/pool with data 1
2018-07-16 12:14:37,078:3180(0x70000c98c000):ZOO_INFO#check_events#1764: initiated connection to server [10.111.129.190:10101]
2018-07-16 12:14:37,107:3180(0x70000c98c000):ZOO_INFO#check_events#1811: session establishment complete on server [10.111.129.190:10101], sessionId=0x10000590d2b0000, negotiated timeout=20000
return value of create = 0
This output has always confused me as zookeeper connection is established after the zookeeper_handle is initiated. It is established upon zoo_create() instead of zookeeper_init. Doesn't effect anything, but just an interesting time to establish a connection.
I understand that retcode=-4 means CONNECTIONLOSS, but it's not even able to establish a connection with the server. If there is anyway I could fix this please do tell!.
I have two simple programs: a client and a server. I'm trying to use zstr_sendfm and zstr_recv to send and receive a simple string. Roughly speaking, I'm using the code from the file transfer test in the zeromq tutorial. Here's the server function:
#define PIPELINE = 10;
int server()
{
char *name = "someName";
zctx_t *ctx = zctx_new();
void *router = zsocket_new(ctx, ZMQ_ROUTER);
zsocket_set_hwm(router, PIPELINE*2);
if (0 == zsocket_connect(router, tcp://127.0.0.1:6000))
{
printf("failed to connect to router.\n");
}
printf( "sending name %s\n, name);
zstr_sendfm( router, name );
return 0;
}
Here's the client function:
int client()
{
zctx_t *ctx = zctx_new ();
void *dealer = zsocket_new (ctx, ZMQ_DEALER);
zsocket_bind(dealer, "tcp://*:6000")
char *receivedName = zstr_recv( dealer );
printf("received the following name: %s\n", receivedName);
return 0
}
Both of these are run in two separate programs (which do nothing other than run their respective functions) on the same computer.
Here's how things always play out:
Start client function, which holds at "zstr_recv" as it's supposed to
Start server function, which connects successfully, claims to have sent the data, and exits
Client function continues to sit and wait, but claims to have not received anything from the server.
What am I missing here? I've added a bunch of error checking and even tried this out in gdb with no luck.
Help and advice appreciated.
I think you have your client and server mixed up, although in ZeroMQ client and server is not as strict as with normal sockets. Normally you would create a server with a REP socket that binds/receives/sends and a client with a REQ socket that connects/sends/receives. You should try this first and then experiment with ROUTER for the server (instead of REP) and DEALER for the client (instead of REQ).
I have to create a program with two parts : Client / Server.
I receive commands from different clients and I want to put the client waiting during the command is executed, but, the other clients must be able to send command to the server
e.g :
C1 (for client 1) and C2 (for client 2)
C1 send command -> server receive it and execute it and he can't accept command from C1 for x seconds but he can accept command from the C2.
How can I do it with select function withous threads.
This is my current code from the server :
void client_ask(t_listplayer *list, t_network *net) {
char *buffer = xmalloc(sizeof(char) * 200);
int rd = 0;
memset(buffer, 0, 200);
while (list != NULL) {
if (FD_ISSET(list->player->fd, &net->readfds)) {
if ((rd = xread(list->player->fd, buffer, 200)) > 0) {
buffer[rd - 1] = '\0';
printf("Client n°: %d asking : [%s]\n", list->player->fd, buffer);
sleep(3); // This one put all the server in waiting
memset(buffer, 0, 200);
} else {
close(list->player->fd);
printf("Client n°: %d has just disconnected", list->player->fd);
}
}
list = list->next;
}
}
So, I've make many research .. I've heard things about timeout but i don't know how to do this.
Thanks
You could manage client-states in your list of clients. If the client state is 'wait', do not answer it (or better : answer "you must wait for x" or some useful feedback). All the clients will be able to send requests and only the one in the correct states will be processed.
Do not forget to reset the client's state when your work is done on its request.
This time I code a chat server and client. The idea is this.
The server uses the select method for with a readfd(FD_SET) to seek which of the clients connected on it have something to send. If it founds something it send it to the rest of clients.
Here is the select function on server and a part of server's code.
SelectResults = select(maxDescriptor+1,&BackUpfdread,NULL,NULL,&time);
I use the select function in client too, to make it seek for incoming and outcoming messages.(these that server sends from other clients and these that this client want to send).
Well, the client in the select function has a fdread and fdwrite (FD_SET).
Here is the part of the code that client has for the connection and for the chat.
The problem is that if i connect two clients on the server message transfer isn't concurrent and that means that clients cannot chat correctly.
Finally i thought to use threads in server. One thread for waiting to receive and one for sending to the clients, but i want to hear and your opinion.
In the client you don't really need that loop from 0 to maxDescriptor. Just check if ConnectSocket is set. Something like this:
// Main loop starts here
for(; ;)
{
memset(SentBuff, 0, sizeof(SentBuff));
printf("Write: ");
gets_s(SentBuff, sizeof(SentBuff));
// Copy the fdread into BackUpfdread and fdwrite to BackUpfdwrite.
BackUpfdread = fdread;
BackUpfdwrite = fdwrite;
SelectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timer);
if(SelectResults == -1)
{
perror("Client-select() error!\n");
exit(1);
}
if (FD_ISSET(ConnectSocket, &BackUpfdread))
{
RecvBytes = recv(ConnectSocket, RecvBuff, sizeof(RecvBuff), 0);
if(RecvBytes > 0)
{
printf("%s\n",RecvBuff);
// Cleaning the Receive Buffer
memset(RecvBuff,0,sizeof(RecvBuff));
}
}
if (FD_ISSET(ConnectSocket, &BackUpfdwrite))
{
SentBytes = send(ConnectSocket, SentBuff,sizeof(SentBuff),0);
// Cleaning the Sent Buffer
memset(SentBuff,0,sizeof(SentBuff));
}
} // Main loop ends here
Also don't forget to check for errors from send and recv. Especially recv is important, as it's the call that will tell you the server has disconnected.
Edit: Another important thing to note, is that the socket may be writeable always, so add a check if there is something to write before you check if the socket is writeable.
My requirement is to connect with the server if it is up ,the client will keep on trying to connect with the server till the successful connection.So I have created the socket fd using the socket() and try to connect using the connect().If the connect fails ,I close the fd using the close().
The expected behaviour is, when the next try the same file descriptor need to be generate by the socket().but for each try the new decriptor only gets created ,since I am closing the file decriptor in case of fail.What may be the issue.Can any one help me.
If you want to repeatedly attempt to connect to a server until a connection is established, just use a loop around a call to connect. socket only binds an endpoint and a file descriptor together.
while (1) {
state = connect(fd, &sa, sizeof sa);
if (state == 0) {
break
} else {
/* Is the server available yet? */
if (errno == ECONNREFUSED) {
/* No, continue trying to connect. */
continue;
} else {
/* Deal with other errors. */
}
}
}