I send this C Server a message w/ netcat.
echo <message> | nc <ip> <port>
it prints:
Client IP : <ip>
I want it to also print:
Client Message : <message>
C SERVER
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
char response[] = "hi";
int main()
{
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 85;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
printf("Client IP : [%s]\n", inet_ntoa(cli_addr.sin_addr));
if (client_fd == -1) {
perror("Can't accept");
continue;
}
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
}
}
You just have to read data from the socket (after the accept call, once you've checked that client_fd is usable):
if (client_fd == -1) {
perror("Can't accept");
continue;
}
printf("Client Message : <");
/* buffer to store result */
char buffer[64] = "";
/* while we can read from socket */
while (read(client_fd, buffer, sizeof buffer-1) > 0)
{
/* write what have been read */
printf("%s", buffer);
}
puts(">");
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
You could also use recv function.
Related
I'm trying to send messages to a server, but when I connect, the server immediately fails receiving the message. It seems that the server "does not wait" for the user to type the message. The server is supposed to remain in that while loop, forever waiting for clients and printing their messages.
I have no idea what's wrong.
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define PORT 4000
#define WORD_SIZE 256
#define USER_SOCKETS 2
#define MAX_USERS 10
int receiveMessage(int socket, char message[])
{
int bytesReceived;
while (1)
{
bytesReceived = recv(socket, message, WORD_SIZE, 0);
if (bytesReceived < 0)
return -1;
if (bytesReceived == 0)
return 0;
}
}
int main(int argc, char *argv[])
{
int serverSockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if ((serverSockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Error creating the socket.\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
if (bind(serverSockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("Error binding the socket..\n");
return -1;
}
if (listen(serverSockfd, 5) < 0)
{
printf("Error on listening.\n");
return -1;
}
int newSockfd;
while (1)
{
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
{
printf("Error on accept a new client.\n");
continue;
}
char username[WORD_SIZE];
if (receiveMessage(newSockfd, username) < 0)
{
printf("Error receiving message.\n");
close(newSockfd);
}
printf("Message: %s\n", username);
close(newSockfd);
}
return 0;
}
Client 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>
#define PORT 4000
int main(int argc, char * argv[]) {
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent * server;
char buffer[256];
if (argc < 2) {
fprintf(stderr, "usage %s hostname\n", argv[0]);
exit(0);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
printf("ERROR opening socket\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = * ((struct in_addr * ) server -> h_addr);
bzero( & (serv_addr.sin_zero), 8);
if (connect(sockfd, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0)
printf("ERROR connecting\n");
printf("Enter the message: ");
bzero(buffer, 256);
fgets(buffer, 256, stdin);
/* write in the socket */
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
printf("ERROR writing to socket\n");
bzero(buffer, 256);
printf("%s\n", buffer);
close(sockfd);
return 0;
}
The line:
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
will set newSockfd to 0 if accept() succeeds, rather than to the descriptor of the socket. This is because < has a higher precedence than =, so the compiler behaves as-if you had written this:
if (newSockfd = (accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0))
You need to write this instead:
if ((newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen)) < 0)
I made a simple Process-based parallel socket program.
My client code reaches the connect part and throws an Invalid argument error, and my server doesn't ouput anything. just cursor...
I split the terminal in two to run the code.
I run the code with:
gcc -o p-server p-server.c -Wall
./p-server
gcc -o p-client p-client.c -Wall
The output is
[C] Connecting...
[C] Can't connect to a Server: Invalid argument
p-server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
//#include <sys/wait.h>
#define BUFFSIZE 4096
#define SERVERPORT 7799
int main(void){
int i, j, s_sock, c_sock;
struct sockaddr_in server_addr, client_addr;
socklen_t c_addr_size;
char buf[BUFFSIZE] = {0};
char hello[] = "Hello~ I am Server!\n";
//int option = 1;
//setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVERPORT);
server_addr.sin_addr.s_addr = inet_addr("10.0.0.131");
s_sock = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
perror("[S] Can't bind a socket");
exit(1);
}
if(listen(s_sock, 5)) {
perror("[S] Can't listen");
exit(1);
}
c_addr_size = sizeof(client_addr);
for ( i=0; i<3; i++) {
if ((c_sock = accept(s_sock, (struct sockaddr *) &client_addr, sizeof(client_addr))) == -1 ){
perror("[S] Can't accept a connection");
exit(1);
}
printf("[S] Connected: client IP addr=%s port=%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
//fork
switch(fork()){
case 0:
close(s_sock);
//1. say hello to client
if(send(c_sock, hello, sizeof(hello)+1, 0) == -1) {
perror("[S] Can't send message");
exit(1);
}
printf("[S] I said Hello to Client!\n");
//2. recv msg from client
if(recv(c_sock, buf, BUFFSIZE, 0) == -1) {
perror("[S] Can't receive message");
exit(1);
}
printf("[S] Client says: %s\n", buf);
exit(0);
}
close(c_sock);
}
/*
for(j=0; j<3; j++){
wait(&status);
printf("Patren waits %d\n"), wstatus;
}*/
}
p-client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFSIZE 4096
#define SERVERPORT 7799
int main(void){
int c_sock;
struct sockaddr_in server_addr;
socklen_t c_addr_size;
char buf[BUFFSIZE] = {0};
char hello[] = "Hi~I am Client!\n";
if((c_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVERPORT);
server_addr.sin_addr.s_addr = inet_addr("10.0.0.131");
printf("[C] Connecting...\n");
if (connect(c_sock, (struct sockaddr *) &server_addr, sizeof(server_addr) == -1)) {
perror("[C] Can't connect to a Server");
exit(1);
}
printf("[C] connected!\n");
//1. recv msg from server (maybe it's "hello")
if (recv(c_sock, buf, BUFFSIZE, 0) == -1) {
perror("[C] Can't receive message");
exit(1);
}
printf("[C] Server says: %s\n", buf);
//2. say hi to server
if(send(c_sock, hello, sizeof(hello)+1, 0) == -1) {
perror("[C] Can't send message");
exit(1);
}
printf("[C] I said Hi to Server!!\n");
printf("[C] I am going to sleep...\n");
sleep(10);
close(c_sock);
return 0;
}
I am Trying to make a C/C++ Project using Socket Programming.
For this I need Client and Server to sent a index of array back and forth to each other.
So Client will next a index of array and server will sent another index of array until the game is over. (Yeah we are trying to make a game.)
I have written (copied from gfg) code for it but it's not working properly.
The Server for some reason didn't receive the second message. So, We kind of stuck in a deadlock.
Any idea what I did wrong??
Server.cpp
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *msg = "0";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
int i=0;
while(i<10)
{
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , msg , strlen(msg) , 0 );
printf("Message sent\n");
i++;
}
return 0;
}
Client.cpp
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *msg="0";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
int i=0;
while(i<10)
{
send(sock , msg , strlen(msg) , 0 );
printf("Message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
i++;
}
return 0;
}
Edit: It will be really nice if somebody can tell me how to sent an integer instead of a string.
I am making a client/server socket program where the client can send a hostname request and the server returns the IP address of the hostname. I do not know what's wrong but my (get_IP) function seems not to work, even though it returns the hostname correctly on the server side. When I change the buffer size on line 109 to 14 and I request "www.google.com", from the client side, it works fine. I suspect that the problem is caused by the buffer. A little help?
Server.c
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#define SERVER_PORT 16700
char *get_IP(char *host)
{
struct hostent *hent;
int iplen = 15;
char *ip = (char *)malloc(iplen+1);
memset(ip, 0, iplen+1);
if((hent = gethostbyname(host)) == NULL)
{
herror("Can't get IP");
exit(1);
}
if(inet_ntop(AF_INET,(void *)hent->h_addr_list[0], ip, iplen) == NULL)
{
perror("Can't resolve the host");
exit(1);
}
return ip;
}
char *host_page(char *ip)
{
int sockfd = 0, n;
char buffer[1024];
struct sockaddr_in host_addr;
char *page = malloc(1024);
memset(buffer, '0' ,sizeof(buffer));
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))< 0)
error("\n Error : Could not create socket \n");
host_addr.sin_family = AF_INET;
host_addr.sin_port = htons(80);
host_addr.sin_addr.s_addr = inet_addr(ip);
if(connect(sockfd, (struct sockaddr *)&host_addr, sizeof(host_addr))<0)
error("\n Error : Connect Failed \n");
n = write(sockfd,"GET", 3);
if (n < 0)
error("\n ERROR: writing to socket");
//getting server response
bzero(buffer,1024);
n = read(sockfd,buffer,1023);
if (n < 0)
error("\n ERROR: reading from socket");
strcpy(page, buffer);
close(sockfd);
return page;
}
int main(void)
{
int sockfd, listenfd = 0,connfd = 0, newsockfd, clilen;
struct sockaddr_in serv_addr, cli_addr;
char buffer[1025];
int n;
/* Establishing communication with socket */
printf("XXXXXX - WELCOME TO PAUL'S PROXY SERVER - XXXXXX \n\n");
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("Connection established... \n\n");
memset(&serv_addr, '0', sizeof(serv_addr));
memset(buffer, '0', sizeof(buffer));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons((unsigned short)SERVER_PORT);
bind(sockfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(listen(sockfd, 10) == -1)
error("Failed to listen\n");
/* start communication with client */
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
if(newsockfd < 0)
error("ERROR on accept");
//getting hostname request
bzero(buffer, 1024);
n = read(newsockfd, buffer, 14);
if (n < 0)
error("ERROR reading from socket");
printf("client requested IP for: %s \n", buffer);
char ip[40];
strcpy (ip, get_IP(buffer));
char page[2000];
strcpy(page, host_page(ip));
//Sending response to client request
n = write(newsockfd, page, 1024);
if(n<0)
error("ERROR reading from socket");
return 0;
}
Client.c
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#define SERVER_IP "129.120.151.94"
#define SERVER_PORT 46700
int main(void)
{
int sockfd = 0, n;
char buffer[1024];
struct sockaddr_in serv_addr;
memset(buffer, '0' ,sizeof(buffer));
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))< 0)
error("\n Error : Could not create socket \n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons((unsigned short)SERVER_PORT);
serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
error("\n Error : Connect Failed \n");
printf("Enter hostname in the form www.host.domain:");
bzero(buffer,1024);
fgets(buffer,1023,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("\n ERROR: writing to socket");
printf("\n hostname IP is: ");
bzero(buffer,1024);
n = read(sockfd,buffer,1023);
if (n < 0)
error("\n ERROR: reading from socket");
printf("%s\n",buffer);
return 0;
}
I am trying to implement a tcp client and tcp server. I am able to establish the connection but when I send a message from the client, the server doesn't receive it and yes I did look at the previous posts and there were alot of similar problems. I did follow them but I am still getting the same error. The error i am getting is from server side:
recv: Socket operation on non-socket
Here is my code. If you can please let me know what I am doing wrong, I would really appreciate it. I think there is a problem in my server implementation.
Server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
#define BACKLOG 10
int main()
{
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[10240];
memset(buffer,0,sizeof(buffer));
int yes = 1;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket failure!!\n");
exit(1);
}
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
memset(&server, 0, sizeof(server));
memset(&dest,0,sizeof(dest));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr )))== -1) { //sizeof(struct sockaddr)
fprintf(stderr, "Binding Failure\n");
exit(1);
}
if ((listen(socket_fd, BACKLOG))== -1){
fprintf(stderr, "Listening Failure\n");
exit(1);
}
while(1) {
size = sizeof(struct sockaddr_in);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
//fprintf(stderr,"Accept Failure\n");
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
//buffer = "Hello World!! I am networking!!\n";
if ((num = recv(client_fd, buffer, 10239,0))== -1) {
//fprintf(stderr,"Error in receiving message!!\n");
perror("recv");
exit(1);
}
// num = recv(client_fd, buffer, sizeof(buffer),0);
buffer[num] = '\0';
printf("Message received: %s\n", buffer);
close(client_fd);
return 0;
//close(socket_fd);
}
}
Client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
int main(int argc, char *argv[])
{
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd,num;
char *buffer;
if (argc != 2) {
fprintf(stderr, "Usage: client hostname\n");
exit(1);
}
if ((he = gethostbyname(argv[1]))==NULL) {
fprintf(stderr, "Cannot get host name\n");
exit(1);
}
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket Failure!!\n");
exit(1);
}
memset(&server_info, 0, sizeof(server_info));
server_info.sin_family = AF_INET;
server_info.sin_port = htons(PORT);
server_info.sin_addr = *((struct in_addr *)he->h_addr);
if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) {
//fprintf(stderr, "Connection Failure\n");
perror("connect");
exit(1);
}
buffer = "Hello World!! I am networking!!\n";
if ((send(socket_fd,buffer, sizeof(buffer),0))== -1) {
fprintf(stderr, "Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else {
printf("Message being sent: %s\n",buffer);
}
close(socket_fd);
}
I ran the server under gdb, and discovered that client_fd is 0 after the call to accept(). This is an invalid socket fd, so I looked at that line of code and noticed that the closing parenthesis is wrong:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
should be:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
Otherwise, it's doing the comparison first and then assigning the comparison to client_fd, whereas you want the assignment of the socket, followed by the comparison.
To avoid this exact kind of frustrating bug, it's generally considered best practice to not put assignments inside of 'if' statements. I would recommend instead:
client_fd = accept(...);
if (client_fd < 0) { ... }
Also, in the client, the call to send() uses "sizeof(buffer)". 'buffer' is a char*, and the sizeof a pointer is 4 (on a 32-bit system), so only 'Hell' will be sent. To send the full string, use "strlen(buffer)" instead for the amount to send.
Your first problem is misplaced parentheses.
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
should actually be
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
As you currently have it, client_fd will be assigned to the result of the equality test between the return value of accept() and -1 and thus will always be zero in case of success.
This is one reason why many programmers avoid assignments in if statements. If written like this
client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size);
if (client_fd == -1) {
then the error can't occur.