Language:
C
Topic:
TCP/IP Socket Programming (Server/Client Architecture)
Source:
http://www.binarytides.com/server-cl...sockets-linux/
This program is using a server/client architecture (over TCP/IP).
I am now experiencing problems with the
server coding.
Main Methods of the Code:
void *wifi_connect(void *arg); Opens socket and listen, accept connections
void *wifi_send(void *arg); Sends message to client
void *wifi_receive(void *arg); Receives message from client and print out
Current condition of the code:
Connecting to client application, sending and receiving messages to/from client application works fine via WIFI on successful connection.
Problem:
When the client application is closed, the server realizes the connection with the client is dropped/disconnected. However, now I'm trying to make the server able to open the socket again and listen for incoming connections again to
reconnect in when the client choose to connect with the server again.
This is my current logic/sequence flow:
- Open socket (Done!)
- Listen and accept any incoming connections from client (Done!)
- Send and Receive msgs upon successful connection with client (Done!)
- Now client disconnects
- I close the socket on server, and re-run the connect method again
- So far, code says Binding done, Accepted Connection, but it just hangs the program without doing anything (suppose to start send/recv)
Server Code:
Code:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h> //socket
#include <string.h> //strlen
#include <arpa/inet.h> //inet_addr
#include <stdbool.h> //boolean
struct WifiConnection {
int socket_desc, c, client_sock;
bool retry, connected, send, rcv;
struct sockaddr_in server, client;
};
struct WifiConnection wifi;
void *wifi_connect(void *arg);
void *wifi_send(void *arg);
void *wifi_receive(void *arg);
void *wifi_connect(void *arg)
{
struct WifiConnection *connect = (struct WifiConnection*)arg;
do {
// Create socket
printf("Allocating Socket... ");
connect->socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (connect->socket_desc == -1) {
printf("\nERROR: Could not create socket\n");
sleep(3);
continue;
} else
printf("Done!\n");
// Prepare the sockaddr_in structure
connect->server.sin_family = AF_INET;
connect->server.sin_addr.s_addr = INADDR_ANY;
connect->server.sin_port = htons( 8888 );
// Bind
printf("Bind socket... ");
if( bind(connect->socket_desc,(struct sockaddr *)&connect->server , sizeof(connect->server)) < 0) {
printf("\nERROR: Bind failed\n");
sleep(3);
continue;
} else
printf("Done!\nWaiting for incoming connections...\n");
// Listen
listen(connect->socket_desc , 10);
// Accept and incoming connection
connect->c = sizeof(struct sockaddr_in);
// Accept connection from an incoming client
connect->client_sock = accept(connect->socket_desc, (struct sockaddr *)&connect->client, (socklen_t*)&connect->c);
if (connect->client_sock < 0) {
perror("Accept failed");
sleep(3);
continue;
}
connect->connected = true;
puts("Connection accepted");
} while (!connect->connected);
return 0;
}
/*----------------------------------------------------------------------------*/
void *wifi_send(void *arg)
{
struct WifiConnection *connect = (struct WifiConnection*)arg;
char message[2000], temp[20];
//Send some data to client
puts("Sending data to client...");
while(1) {
strcpy(message,"some things here");
if(send(connect->client_sock , message , strlen(message)+1 , 0) < 0)
{
puts("Error sending from socket (Probably disconnected)");
close(connect->socket_desc);
puts("Connections closed. Reconnecting...");
wifi_connect(connect);
}
// Clear buffer
memset(message, 0, sizeof message);
}
return 0;
}
/*----------------------------------------------------------------------------*/
void *wifi_receive(void *arg)
{
struct WifiConnection *connect = (struct WifiConnection*)arg;
char message[2000];
// Receive a message from client
puts("Receiving data from client...");
while(1) {
if(recv(connect->client_sock, message, 2000, 0) > 0 ) {
printf("Incoming Message: %s\n", message);
}
else {
puts("Error reading from socket (Probably disconnected)");
close(connect->socket_desc);
puts("Connections closed. Reconnecting...");
wifi_connect(connect);
}
// Clear buffer
memset(message,0,sizeof message);
}
return 0;
}
/*----------------------------------------------------------------------------*/
int main(void)
{
int rc;
bool wifi_init = false;
void *status;
wifi_connect((void *)&wifi);
while(!wifi_init) {
if(wifi.connected && !wifi_init) {
wifi_send((void *)&wifi);
wifi_receive((void *)&wifi);
wifi_init = true;
}
}
/*----------------------------------------------------------------------------*/
// removed multithreading codes for simplicity.
// in actual implementation theres pthread_join calls to ensure
// the codes below will run after the program choose to exit.
/*----------------------------------------------------------------------------*/
// Close all connections
close(wifi.socket_desc);
return 0;
}
Output:
Code:
Allocating Socket... Done!
Bind socket... Done!
Waiting for incoming connections...
Connection accepted
Receiving data from client...
Sending data to client...
Incoming Message: hi
Error reading from socket (Probably disconnected)
Connections closed. Reconnecting...
Allocating Socket... Done!
Bind socket... Done!
Waiting for incoming connections...
Connection accepted
^C ---- i have to manually terminate it since it stucks here forever
Help appreciated! Thank you!
PS. very new to C so not very sure about many things!
EDIT: Removed multithreading codes for simplicity. Please just assume that sending and receiving methods will still keep running when connection with client is lost.
EDIT: Problem seem to be resolved so far. Might be due to other parts of my code.