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
Related
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?
sometimes, expecially when client and server are on different machines (one in my ubuntu and the other one in a virtual-machined ubuntu), the client which tries to connect to the server via hostname gets a
Error getHostEntry: Resource temporarily unavailable.
This is the server.c file:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/un.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <malloc.h>
#include <netdb.h>
void checkHostname(int);
void checkHostEntry(struct hostent*);
void checkIpBuffer(char*);
int main(int argc, char **argv) {
struct sockaddr_in socketAddress;
int socketDescriptor, clientDescriptor, nread;
char buffer[1000];
pthread_t threadId;
char hostbuffer[256];
char *IPbuffer;
struct hostent *hostEntry;
int hostname;
if((socketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Errore durante la creazione della socket\n");
exit(1);
}
socketAddress.sin_family = AF_INET;
socketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
socketAddress.sin_port = htons(atoi(argv[1]));
if(bind(socketDescriptor, (struct sockaddr*) &socketAddress, sizeof(socketAddress)) != 0) {
printf("Errore di bind()\n");
close(socketDescriptor);
exit(1);
}
hostname = gethostname(hostbuffer, sizeof(hostbuffer));
checkHostname(hostname);
hostEntry = gethostbyname(hostbuffer);
checkHostEntry(hostEntry);
IPbuffer = inet_ntoa(*((struct in_addr*) hostEntry->h_addr_list[0]));
printf("Hostname - %s\n", hostbuffer);
printf("Host IP - %s:%d\n", IPbuffer, ntohs(socketAddress.sin_port));
if(listen(socketDescriptor, 100) < 0) {
printf("Errore di listen()\n");
close(socketDescriptor);
exit(1);
}
return 0;
}
void checkHostname(int hostname) {
if (hostname == -1) {
perror("Errore gethostname");
exit(1);
}
}
void checkHostEntry(struct hostent *hostentry) {
if (hostentry == NULL) {
perror("Errore getHostEntry");
exit(1);
}
}
void checkIpBuffer(char *ip) {
if (ip == NULL) {
perror("Errore inet_ntoa");
exit(1);
}
}
And this is my client.c file
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <netdb.h>
int main(int argc, char **argv) {
struct sockaddr_in clientAddress;
int choice, nread, serverIp;
char *IPbuffer;
struct hostent *host_entry;
if((clientDescriptor = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Errore nella creaione del socket\n");
exit(1);
}
host_entry = gethostbyname(argv[1]);
checkHostEntry(host_entry)
IPbuffer = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
clientAddress.sin_family = AF_INET;
clientAddress.sin_addr.s_addr = inet_addr(IPbuffer); // indirizzo IP
clientAddress.sin_port = htons(atoi(argv[2])); // porta
if(connect(clientDescriptor, (struct sockaddr*) &clientAddress, sizeof(clientAddress)) < 0) {
printf("Errore connect()\n");
close(clientDescriptor);
exit(1);
}
return 0;
}
void checkHostEntry(struct hostent *hostentry) {
if (hostentry == NULL) {
perror("Errore getHostEntry");
exit(1);
}
}
If I
./server.out 8888
it displays:
IP: 1.2.3.4
Hostname: johnmayer
and If i try to connect from another computer (with a ubuntu installed on a virtual box) to this server, using
./client johnmayer 8888
I sometimes get
Error getHostEntry: Resource temporarily unavailable.
Is there something wrong in the code?
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've written the client code and the server, however, there is a problem with connect: "No route to host". It is strange because clients and servers operate in a different network. Also, if I ping [my ip] tells me timeout, if I telnet [my ip] tells me error. Can you advise me how to solve this problem? I opened port 2222 from the router but it still does not seem to work.
Sorry for my English
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#define ADDRESS "[IP]"
#define PORT 2222
int main()
{
int sockid;
struct sockaddr_in c_address;
printf("[CLIENT] Eseguito.\n");
c_address.sin_family = AF_INET;
c_address.sin_addr.s_addr = inet_addr(ADDRESS);
c_address.sin_port = htons(PORT);
sockid = socket(AF_INET, SOCK_STREAM, 0);
int sock_conn;
sock_conn = connect(sockid, (struct sockaddr *)&c_address, sizeof(c_address));
if(sock_conn == -1)
{
perror("Connect client");
exit(EXIT_FAILURE);
}
while(1)
{
char text[128];
printf("[CLIENT] Scrivi qualcosa: ");
fgets(text, 128, stdin);
write(sockid, text, 128);
read(sockid, text, 128);
printf("[CLIENT] Testo ricevuto: %s.\n", text);
}
}
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#define PORT 2222
void toggleCharacter(char *str);
int main()
{
int sockid;
struct sockaddr_in s_address;
printf("[SERVER] Eseguito.\n");
s_address.sin_family = AF_INET;
s_address.sin_addr.s_addr = htonl(INADDR_ANY);
s_address.sin_port = htons(PORT);
sockid = socket(AF_INET, SOCK_STREAM, 0);
if(bind(sockid, (struct sockaddr *)&s_address, sizeof(s_address)) == -1)
{
perror("Bind server");
exit(EXIT_FAILURE);
}
if(listen(sockid, 5) == -1)
{
perror("Listen server");
exit(EXIT_FAILURE);
}
int connection_socket;
connection_socket = accept(sockid, NULL, 0);
if(connection_socket == -1)
{
perror("Accept server");
exit(EXIT_FAILURE);
}
char text[128];
while(1)
{
read(connection_socket, text, 128);
printf("[SERVER] Messaggio ricevuto: %s.\n", text);
printf("[SERVER] Scrivi qualcosa: ");
fgets(text, 128, stdin);
write(connection_socket, text, 128);
}
close(connection_socket);
}
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.