I am quite new to C & Linux and I tried to setup a TCP socket server for Data exchange with a C-Code I compiled and executed on a Ubuntu System.
From a Tutorial I copied the following code (see below, the original version didn't include exception handling) and it worked to start the server and receive data (time & date) with a client code (on the same machine for test purpose).
Then I restarted the Ubuntu machine and since then I can't start the server anymore.
I then added exception handling to the code below and it throws "unable to bind" with errorno 22, which means "invalid argument"? This doesn't make sense to me, as the same code worked before quite good.
I assumed that the "old" socket is in a time-wait state or not closed yet, but I checked all connections with "ss -all state xxx" for all different states and everything seems alright.
Also tried to use different ports and codes - same problem.
Hope anyone can help me with this problem as I don't know what else to try.
// C-Code Server
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
//Open a socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
if (listenfd == -1) {
printf("Error: unable to open a socket\n");
exit(1);
}
//Create an Adress
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
serv_addr.sin_port = htons(1234);
//Macht schon benutzte Adresse mit SO_REUSEADDR nutzbar
int opt = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))<0) {
perror("setsockopt");exit(EXIT_FAILURE);
}
if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(opt))<0) {
perror("setsockopt");exit(EXIT_FAILURE);
}
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if ((bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) == -1) {
printf("Error: unable to bind\n");
printf("Error code: %d\n", errno);
exit(1);
}
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
if (connfd == -1) {
printf("Error: unable to accept connections\n");
printf("Error code: %d\n", errno);
exit(1);
}
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Related
Story : I tried compiling the code below on Sli-Taz Linux 32 bit, as well as on 64 bit. In both cases I get the same gcc error. I searched for libc packages in the repo and could not find anything named libc-dev. If I can not find a solution, I may also try it with Alpine Linux.
Compile error for : gcc server.c
In file included from /usr/include/sys/socket.h:40:0,
from server.c:5:
/usr/include/bits/socket.h:381:24: fatal error: asm/socket.h: No such file or directory
compilation terminated.
Code for : server.c
#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[] = "test";
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 = 90;
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);
}
Description of the server.c : It is a program that will listen to port 90 and if a client tries to connect to port 90, it will respond to them with the message : test.
You need to install the linux-api-headers package.
/usr/include/asm/* are APIs exposed by the kernel and so are generally taken from the kernel source and updated as you upgrade the installed kernel. In SliTaz this is the linux-api-headers package; in Red Hat-derived systems this is the kernel-headers package, or Ubuntu it's linux-headers or linux-headers-generic, etc.
I have written a basic client server code in c socket programming using the TCP/IP protocol but i cant figure out how to make it connect to different clients and send/receive different data to and from them as a function to the client (meaning if its the first client send him that data and if its that client send him the other data) and so on.
This is the only results i have found were sending the same data to different clients.
Current Server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
int main() {
char server_message[100] = {0};
int server_socket = 0;
int client_socket = 0;
struct sockaddr_in server_address;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
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, 2);
client_socket = accept(server_socket, NULL, NULL);
printf("Please enter a massage:");
fgets(server_message, 100, stdin);
send(client_socket, server_message, sizeof(server_message), 0);
close(server_socket);
return 0;
}
By using original code from geeksforgeeks and Myst comment we can solve it.
You have one server that serves on local host 127.0.0.1, and can have multiple clients for this example i assume 5 clients are enough.
Run server once, and run many client to connect seprately to that server.
Server.c
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
#define STRING_SIZE 100
#define BUFFER_SIZE 100
int main(int argc, char const *argv[])
{
int server_fd, new_socket[5], valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// 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);
}
for (int i=0;i<5;i++){
if ((new_socket[i] = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read(new_socket[i], buffer, 1024);
printf("%s\n", buffer);
char send_buf[STRING_SIZE] = "hello";
char buf[BUFFER_SIZE]={0};
sprintf(buf, "%d", i);
strcat(send_buf, buf);
send(new_socket[i], send_buf, strlen(send_buf), 0);
//printf("Hello message sent\n");
}
return 0;
}
Client.c
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
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;
}
send(sock , hello , strlen(hello) , 0 );
//printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n", buffer);
return 0;
}
Run
After compiling codes with gcc client.c -o client and gcc server.c -o server
Open one terminal for server and start server by run ./server.
Now you can connect many client [up to 5] to it by running ./client.
I'm writing 2 small test programs in C (client/server) and I'm having trouble sending messages from the server to the client (but the other way around works just fine). The server says it sent 20 bytes, but on the client's end it says "failed to receive data". I would appreciate any help, thank you so much! My code is below:
Server:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
int main(int argc, char* argv[])
{
int sockfd, client_sockfd;
struct sockaddr_in server;
int reading, fileSize;
int i; //counter
int bytesSent;
char test[20] = "test message\n";
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1])); //assign port to listen to
server.sin_addr.s_addr = INADDR_ANY; //IP address
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //create socket failed
{
perror("socket");
exit(1);
}
if(bind(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) //connect server socket to specified port
{
perror("bind call failed");
exit(1);
}
//printf("listening to port %d\n", server.sin_port);
if(listen(sockfd, 5) == -1) //queue size of 5
{
perror("listen call failed");
exit(1);
}
while(1) //infinite loop to process connections from clients
{
client_sockfd = accept(sockfd, NULL, NULL); //accept anything
if(client_sockfd == -1)
perror("accept call failed");
bytesSent = send(client_sockfd, test, 20, 0);
printf("bytes sent: %d\n", bytesSent);
}
close(client_sockfd);
close(sockfd);
return 0;
}
Client:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in server;
struct hostent *server_ip_address;
server_ip_address = gethostbyname("eos-class.engr.oregonstate.edu");
int sent; //number of bytes sent
int received; //number of bytes received
char passedMsg[20]; //holds received message
if(server_ip_address == NULL)
{
fprintf(stderr, "could not resolve server host name\n");
exit(1);
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[3])); //assign port to connect to
memcpy(&server.sin_addr, server_ip_address->h_addr, server_ip_address->h_length);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //create socket failed
{
perror("socket");
exit(1);
}
if(connect(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) //connect socket to remote address failed
{
printf("tried to connect to port %d\n", server.sin_port);
perror("connect");
exit(1);
}
if((received = recv(sockfd, passedMsg, 20, 0)) < 0);
{
printf("Failed to receive data\n");
exit(1);
}
printf("Received message: %s\n", passedMsg);
close(sockfd);
return 0;
}
In your client code, in the error checking for recv, change printf to perror. If you do, the output will be:
Failed to receive data: Success
So the recv call was successful, but the error code ran anyway. Why? Let's take a closer look at that if statement:
// what's this? ----v
if((received = recv(sockfd, passedMsg, 20, 0)) < 0);
{
printf("Failed to receive data\n");
exit(1);
}
There's a stray ; after the condition in the if statement. This means that the if statement does nothing if the condition is true, and that the following block is not the body of the if but an independent block that always runs.
Get rid of the extra ; and you get the expected results.
This code is generating "Connection Failed error", (the error generating portion is commented below in the code) even when i am supplying the correct input format eg.
./Client ip text portno
./Client 127.0.0.1 "tushar" 7100
//AUTHOR: TUSHAR MAROO
//Client.c
//header files used
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
//constants
#define RCVBUFFERSIZE 32
//functions used
void DieWithError(char *errorMessage);
//main program
int main(int argc, char *argv[]){
int sock;
struct sockaddr_in serverAddr;
unsigned short serverPort;
char *serverIp;
char *message;
unsigned int messageLength;
char buffer[RCVBUFFERSIZE];
//condition check deplyed for nuber of arguements not for data in arguements
if((argc<3) || (argc>4)){
fprintf(stderr,"Format: %s <Server's IP> <Your Message> <Port Number>\n",argv[0]);
exit(1);
}
serverIp = argv[1];
message = argv[2];
if(argc == 4){
serverPort = atoi(argv[3]);
} else {
serverPort = 7;
}
//create a socket and check success and handle error
if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 )
fprintf(stderr, "Socket Creation Fail");
//server details
//bzero((struct sockaddr_in *)(&serverAddr),sizeof(serverAddr));
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(serverIp);
serverAddr.sin_port = htons(serverPort);
printf("tusharmaroo");
//not working why??
//if (connect(sock, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
//DieWithError("Connection Error..");
//fprintf(stderr,"Connection error");
//this snippet also not working
if (connect(sock, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
DieWithError("connect() failed");
printf("connected....");
messageLength = strlen(message);
if(send(sock, message, messageLength, 0) > 0)
printf("message sent....");
close(sock);
exit(0);
}
//AUTHOR TUSHAR MAROO
//SERVER CODE
//header files
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
//constants declared
#define ALLOWEDCONNECTIONS 5
//external functions
void DieWithError(char *error);
void ClientHandle(int sock);
//main code
int main(int argc, char argv[]){
int serverSock;
int clientSock;
struct sockaddr_in serverAddr;
struct sockaddr_in clientAddr;
unsigned int serverPort;
unsigned int clientLength;
if(argc != 2){
fprintf(stderr,"Format: %d <Port No.>", argv[0]);
//DieWithError("Pass Correct Number of Arguements...");
exit(1);
}
if((serverSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
DieWithError("Socket not Created");
exit(1);
}
serverPort = htons((argv[1]));
//assign address to the server
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(serverPort);
//socket has been created now bind it to some ip and port
if((bind(serverSock,(struct sockaddr *)&serverAddr,sizeof(serverAddr))) < 0){
DieWithError("Binding Failed");
}
if(listen(serverSock,5) < 0){
DieWithError("Listen Failed");
}
for(;;){
clientLength = sizeof(clientAddr);
if((clientSock = accept(serverSock, (struct sockaddr *) &clientAddr, &clientLength)) < 0){
DieWithError("Accept() failed");
exit(1);
}
printf("Handling Client %s ",inet_ntoa(clientAddr.sin_addr));
}
return 0;
}
This is wrong in the server code
serverPort = htons((argv[1]));
This should be
serverPort = htons(atoi(argv[1]));
Are you sure there are no firewall rules causing troubles for you? Ensure that.
If the connect fails you should be able to print out the error using perror or strerror:
perror("Could not connect:");
works for me
client and server are ubuntu 12.04
for server, run in a shell
nc -l 9999
This is on a host with the address "192.168.56.13"
for client, compile code above with "DieWithError" fixed up
void DieWithError(char *errorMessage) { printf("%s",errorMessage); exit(1); }
cc -o foo foo.c
./foo 192.168.56.13 "hello" 9999</strike>
replace the DieWithError() with perror() Then I would guess that it will print out "connection refused" as you seem to have a networking problem with getting the server running on the correct address.
However, if the address in your client is correct the nc program WILL print "hello"
you just altered your program the previous version worked for me. The current version, I don't know if it does.
Like everyone else is saying, use perror() to get proper diagnostics
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.