How to receive data from client on server via sockets - c

I am trying to send data from my client to server, but my server isn't receiving the message, I am not sure why. The client receives Connected message and it's displaying. How can I get the server to receive messages from client? Also, should I use close() function in the server for loop?
Client
int main(){
char server_response[256];
char send_msg[256] = "Sending to server";
int server;
server = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(9002);
address.sin_addr.s_addr=INADDR_ANY;
int con = connect(server,(struct sockaddr*) &address, sizeof(address));
if(con == -1) {
printf("Error with connection");
return -1;
}
recv(server, server_response, sizeof(server_response), 0);
int toServer = send(server, send_msg, sizeof(send_msg), 0);
if(toServer == -1) {
perror();
}
printf("%s", server_response);
return 0;
}
Server
int main(){
char server_response[256] = "Connected";
int server;
char from_client[256];
server = socket(AF_INET, SOCK_STREAM, 0);
if(server == -1) {
perror();
return -1;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(9002);
address.sin_addr.s_addr=INADDR_ANY;
int bindx = bind(server,(struct sockaddr*) &address, sizeof(address));
if(bindx == -1) {
perror();
return -1;
}
listen(server, 5);
for(;;) {
int client_socket = accept(server, NULL, NULL);
send(client_socket, server_response, sizeof(server_response), 0);
recv(client_socket, from_client, sizeof(from_client), 0);
printf("%s", from_client);
}
return 0;
}

It seems you have some synchronization problem. That is either server and client both are in send mode or both in recv mode. It's better to follow a request-response pattern which means server be in listening mode after accept the client. So change the server code to recv/printf/send pattern and client to send/receive mode or just send mode.
Server:
int main(){
char server_response[256] = "Connected";
int server;
char from_client[256];
server = socket(AF_INET, SOCK_STREAM, 0);
if(server == -1) {
perror();
return -1;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(9002);
address.sin_addr.s_addr=INADDR_ANY;
int bindx = bind(server,(struct sockaddr*) &address, sizeof(address));
if(bindx == -1) {
perror();
return -1;
}
listen(server, 5);
for(;;) {
int client_socket = accept(server, NULL, NULL);
recv(client_socket, from_client, sizeof(from_client), 0);
printf("%s", from_client);
send(client_socket, server_response, sizeof(server_response), 0);
}
return 0;
}
Client:
int main(){
char server_response[256];
char send_msg[256] = "Sending to server";
int server;
server = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(9002);
address.sin_addr.s_addr=INADDR_ANY;
int con = connect(server,(struct sockaddr*) &address, sizeof(address));
if(con == -1) {
printf("Error with connection");
return -1;
}
int toServer = send(server, send_msg, sizeof(send_msg), 0);
if(toServer == -1) {
perror();
}
recv(server, server_response, sizeof(server_response), 0);
printf("%s", server_response);
return 0;
}
And stare server before client. See online demo provided.

Related

How to send a message from server to client in C

Hey guys I want to send a message of the current date from the server to a client in C.
So I would use a command like this for the client;
Terminal
telnet localhost PORT
What should be the command to send the actual message?
int main(int argc, char *argv[])
{
int socket_desc, client_sock, c, read_size;
struct sockaddr_in server, client;
char client_message[2000];
time_t t = time(NULL);
struct tm tm = *localtime(&t);
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
listen(socket_desc, 3);
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
////////////////////////////////////////////////////
//the actual message here
////////////////////////////////////////////////////
close(socket_desc);
return 0;
}
I made the following addiction and it worked
Is this a proper solution? I don't know how to use send() properly yet.
pid_t child_pid = fork();
if (child_pid == 0)
{
snprintf(client_message, sizeof(client_message), "%s", ctime(&tick));
write(client_sock, client_message, strlen(client_message));
shutdown(client_sock, SHUT_RDWR);
while (read(client_sock, client_message, sizeof(client_message) > 0))
close(client_sock);
}
else if (child_pid > 0)
{
// parent
close(client_sock);
}
else
{
// a fork error occurred, handle and remember to close(connfd)
}

Socket server in C stuck on call to function send() and not passing through it

I try to make a Socket client/server bundle running at the same time, passing information to one another. The problem is, after sending the first piece of data from the client, the server returns the answer correctly but becomes stuck on the call to function send(), disabling the ability for the server to receive another data from the client.
I use the following pieces of code in server and client:
Client Code
char requestToSend[1000] = "Some request";
int client_socket;
struct sockaddr_in servaddr;
client_socket = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
connect(client_socket, (SA*)&servaddr, sizeof(servaddr));
char buffer[MAX];
bzero(buffer, sizeof(buffer));
send(server_socket, requestToSend, sizeof(requestToSend), 0);
bzero(requestToSend, sizeof(requestToSend));
while (strcmp(requestToSend, "") == 0) {
recv(server_socket, requestToSend, sizeof(requestToSend), 0);
}
shutdown(client_socket, SHUT_RDWR);
printf("Received: %s", requestToSend); // requestToSend is not the received result!
Server Code
The following code should return "My new result" in response to any request from the client.
while (1) {
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, sizeof(buffer), 0);
shutdown(server_socket, SHUT_RDWR);
}
There are other questions on Stack Overflow mentioning the problem of send() being stuck, but they don't provide an answer to this question.
You should only open and bind the server socket once. The loop should start before the accept() call. And you should close the client socket, not just call shutdown().
When you're sending the reply, you should just send strlen(buffer)+1 bytes, not sizeof(buffer). The latter will send MAX bytes, which will include lots of uninitialized bytes. Adding 1 to strlen() will include the null byte.
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
while (1) {
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, strlen(buffer)+1, 0);
close(client_socket);
}
The client's recv() loop should loop until it receives 0, which indicates that the server has closed the socket. Each call should append to the buffer, not overwrite it.
char *ptr = requestToSend;
size_t len = sizeof(requestToSend);
int nread;
while ((nread = recv(server_socket, ptr, len, 0)) != 0) {
if (nread < 0) {
perror("recv from server");
exit(1);
}
ptr += nread;
len -= nread;
}
And it should also close the socket, not use shutdown(). shutdown() is generally only used when you want to half-close a socket -- you want to send EOF to the other system, but continue to read its responses.

my recv breaks my send which is just before

I'm trying to make a program that uses sockets between a client and a server. In my code below if I comment on the loop while my server receives my message but if I do not comment my client seems not to send my message (finally my server never receives my message). Why ?
Server
int main()
{
message = malloc(sizeof(char));
printf("Waiting for incoming connections ...\n");
sem_init(&lock, 0, 1);
// socket creation
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// dserver address9002
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, MAX_CONNECTIONS);
int client_socket;
int i = 0;
while(client_counter < 2 && (client_socket = accept(server_socket, NULL,NULL)))
{
client_counter++;
client_sockets[i] = client_socket;
i++;
printf("new client ! \n");
}
//here i create a thread for each client and in this thread there is a while loop with a recv function
}
Client
int socket_connection(char* ip, int port)
{
int network_socket = 0;
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
server_address.sin_addr.s_addr = inet_addr(ip);
if ((network_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
int connection_status = connect(network_socket, (struct sockaddr*) &server_address, sizeof(server_address));
if (connection_status < 0)
{
printf("Error while creating / connecting the socket");
return -1;
}
return network_socket;
}
void connect_to_server()
{
char ip[256];
int port;
strcpy(ip, "127.0.0.1");
port = 9002;
// try to connect to the server with the IP and port
int network_socket = socket_connection(ip, port);
char server_reponse[256];
char message[256];
// clean string
memset(server_reponse, 0, sizeof(server_reponse));
recv(network_socket, &server_reponse, sizeof(server_reponse), 0);
if (strcmp(server_reponse, "instruction: make board") == 0)
{
construct_game_board();
show_game_board();
memset(message, 0, sizeof(message));
put_ship(message);
printf("Finish to make board\n");
}
printf("Reponse send to socket %d: %zu\n",network_socket, send(network_socket, message, strlen(message), 0));
while (1) {
printf("Before recv\n");
printf("Reponse recv : %zu\n", recv(network_socket, server_reponse, sizeof(server_reponse), 0));
printf("After recv\n");
}
In my console when i launch i have : Reponse send to socket 3: 0 and Before recv

Cant make a tcp connection just one after the other

I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :
CLIENT :
int main() {
char buf[256] = "In client";
// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);
int status = connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{
printf("There Was an error!");
}
recv(sock, buf, sizeof(buf), 0);
printf("\n %s \n", buf);
close(sock);
return 0;
}
SERVER:
int main() {
char server_message[256] = "You have reached the server!";
// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 5);
int client_socket;
client_socket = accept(server_socket, NULL, NULL);
// send the message
send(client_socket, server_message, sizeof(server_message), 0);
// close the socket
close(server_socket);
return 0;
}
The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.
Can anyone help why is this occurring?
Thanks in advance!
You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.
You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.
int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed");
(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)
Check out my whole code here and see how it runs.
This is the server
int main(){
SOCKET s, newsocket;
struct sockaddr_in server, client;
int receiving;
char clientMessage[2000], *message;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socker error at %d", GetLastError());
}else{
puts("socket created");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("err at binding %d", GetLastError());
}else{
puts("binded.");
}
listen(s, 3);
puts("listening to connections...");
int c = sizeof(struct sockaddr_in);
while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
puts("connection accepted");
//send
message="hello client";
send(newsocket, message, strlen(message), 0);
recv(newsocket, clientMessage, 50, 0);
puts(clientMessage);
}
puts("waiting for a machine");
if(newsocket == INVALID_SOCKET){
printf("newsocket invalid at %d", GetLastError());
}
getchar();
closesocket(s);
WSACleanup();
}
This is the client
int main(){
SOCKET s;
struct sockaddr_in server;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error At %d", GetLastError());
}else{
puts("socket initialised");
}
server.sin_port = htons(8080);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("176.40.201.72");
printf("server values are defined.. \n");
printf("connecting..\n");
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection error %d" , GetLastError());
}else{
puts("connected");
}
return 0;
}

C Sockets - send() sends, recv() not receiving

So I'm doing some client server stuff here, and I want my server to listen for clients, and when a client connects to the server, the client sends a string.
The connection establishes, the clients sends it's string, but, at server side, recv() returns -1.
/* Server */
int main() {
int fd, conn_fd;
struct sockaddr_in ad;
int bytes;
char recv_buffer[256];
fd = socket(AF_INET, SOCK_STREAM, 0);
ad.sin_family = AF_INET;
ad.sin_port = htons(3335);
ad.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd, (struct sockaddr*)&ad, sizeof(ad));
listen(fd, 5);
conn_fd = accept(fd, (struct sockaddr*)0, 0);
bytes = recv(fd, recv_buffer, sizeof(recv_buffer), 0);
printf("%d\n", bytes);
return 0;
}
The clients simply connects to the server:
/* Client */
int main() {
int fd, n;
unsigned int s;
struct sockaddr_in addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(3335);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
char buff[256] = "time";
printf("Connecting to server....\n");
if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
printf("connect() error.\n");
exit(1);
}
s = send(fd, buff, sizeof(buff), 0);
return 0;
}
Thanks!
I found out what the problem was. In my server code, I was using the wrong socket descriptor for recv(): instead of fd, I should have used conn_fd.

Resources