I have to do an assignment for my one lecture where i have to create a connection between a client and a server program in C. The server program and the client program have to run on different PC’s. After starting the server.c with:
- gcc server.c -o server
- ./server // number is part of the packet.h
The server stops at "Listening…" which is correct.
After that i started the client.c with:
- gcc client.c -o client
- ./client
The program trows a perror ": Connection refused" after checking the connect()-function. There has to be the problem but I can’t fix it.
I tried to figure out the exact problem. Here are a few things i already tried:
- The server is 100% in my local internet. I tried with "netcat " to search for the server and the server is there.
- I always used a port bigger than 5000 in my home network and in my uni network 50000 (the only one that can be used, my professor told me that).
- I was working on ubuntu and i always wrote "%eth0" behind the ipv6.
- I checked out a bunch of other codes and mine looked nearly the same.
- I tried to debug the "client.c" file and the connect()-function always gave back -1. I think there has to be the problem but I could not fix that.
Here is my code:
Server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
// #include <libc.h>
#include "packet.h"
int main(int argc, char *argv[]){
if(argc != 4){ // Test ob 4 Programmargumente mitgegeben wurden
fprintf(stderr, "- Error: %s <IPv6 address> <port> <sNummer>n", argv[0]);
exit(1);
}
struct packet received_packet, send_packet;
const char *ip = argv[1];
char* endptr;
long port_long = strtol(argv[2], &endptr, 10);
if(*endptr != '' || port_long < 0 || port_long > UINT16_MAX){
fprintf(stderr, "- invalid port number: %sn", argv[2]);
exit(1);
}
uint16_t port =(uint16_t)port_long;
long sNummer_long = strtol(argv[3], &endptr, 10);
if(*endptr != '' || sNummer_long < 0 || sNummer_long > UINT32_MAX){
fprintf(stderr, "- invalid sNummer: %sn", argv[3]);
exit(1);
}
send_packet.sNummer = (uint32_t)sNummer_long;
int csocket;
struct sockaddr_in6 addr;
socklen_t addrsize;
char test[1024];
csocket = socket(AF_INET6, SOCK_STREAM, 0);
if(csocket < 0 ){ // Test ob TCP-Socket erstellt wurde
perror("- socket errorn");
exit(1);
}
printf("+ TCP server socket createdn");
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
inet_pton(AF_INET6, ip, &addr.sin6_addr);
if( connect(csocket, (struct sockaddr *) &addr, sizeof(addr)) < 0 ){
perror("- could not connect to servern");
exit(1);
}
printf("+ Connected to server %s on port %dn",ip, port);
printf("n ----- message -----n");
printf("text: ");
scanf("%s",send_packet.text);
printf("s%d > %sn",send_packet.sNummer, send_packet.text);
send(csocket, &send_packet, sizeof(send_packet), 0);
ssize_t bytesRead = recv(csocket, &received_packet, sizeof(received_packet), 0);
if( bytesRead <= 0 ){
perror("- error receiving data from servern");
}
test[bytesRead] = '';
printf("n ----- Server -----n");
printf("s%d > %sn",received_packet.sNummer,received_packet.text);
close(csocket);
printf("n+ disconnected from servern");
return 0;
}
Client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
// #include <libc.h>
#include "packet.h"
#define BACKLOG 5
int main(int argc, char *argv[]){
if(argc != 3){ // Test ob auch 3 Programmargumente mitgegeben wurden
fprintf(stderr, "- Error: %s <port> <sNummer>n",argv[0]);
exit(1);
}
struct packet received_packet, response_packet;
char* endptr;
long port_long = strtol(argv[1], &endptr, 10);
if(*endptr != '' || port_long < 0 || port_long > UINT16_MAX){
fprintf(stderr, "- invalid port number: %sn", argv[1]);
exit(1);
}
uint16_t port =(uint16_t)port_long;
long sNummer_long = strtol(argv[2], &endptr, 10);
if(*endptr != '' || sNummer_long < 0 || sNummer_long > UINT32_MAX){
fprintf(stderr, "- invalid sNummer: %sn", argv[2]);
exit(1);
}
response_packet.sNummer = (uint32_t)sNummer_long;
int server_socket, client_socket;
struct sockaddr_in6 s_addr, c_addr;
socklen_t c_addrsize;
char test[1024];
server_socket = socket(AF_INET6, SOCK_STREAM, 0);
if(server_socket < 0 ){
perror("- socket errorn");
exit(1);
}
printf("+ TCP server socket createdn");
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin6_family = AF_INET6;
s_addr.sin6_port = htons(port);
s_addr.sin6_addr = in6addr_any;
if(bind(server_socket, (struct sockaddr *) &s_addr, sizeof(s_addr)) < 0){
perror("- bind errorn");
exit(1);
}
printf("+ bind to port number: %dn", port);
if(listen(server_socket, BACKLOG) < 0){
perror("- listening error, can't hear somethingn");
exit(1);
}
printf("Listening...n");
while(1){
c_addrsize = sizeof(c_addr);
client_socket = accept(server_socket, (struct sockaddr*)&c_addr, &c_addrsize);
if(client_socket > 0){
printf("+ Client connectedn");
}else {
printf("- No Client connectedn");
sleep(1);
continue;
}
ssize_t bytesRead = recv(client_socket, &received_packet, sizeof(received_packet), 0);
if( bytesRead <= 0 ){
perror("- error receiving data from clientn");
continue;
}
test[bytesRead] = '';
printf("n ----- Client -----n");
printf("s%d > %sn",received_packet.sNummer, received_packet.text);
printf("n ----- response -----n");
printf("text: ");
scanf("%s",response_packet.text);
send(client_socket, &response_packet, sizeof(response_packet), 0);
close(client_socket);
printf("n+ Client disconnectedn");
}
return 0;
}
and finally the packet.h. This packet is part of my assignment. It hast to be send from the client to the server and back.
#ifndef PACKET_H
#define PACKET_H
#include <stdint.h>
struct packet {
char text[1024];
uint32_t sNummer;
};
#endif
2
Answers
Ok thank you a lot guys. I asked a laboratory employee and he said that port 50000 is blocked in ubuntu. I started my program in a linux bash on a windows computer and it worked perfectly fine. :)
There seems to be nothing wrong with the code. Just make sure you are using the right ipv6 address.
On the server, run
ip address
orifconfig
; forip address
, the output will be like this:Use ipv4 or ipv6 (both work with your code). E.g.: my ipv4:
192.168.0.105/24
(you Will need/24
part for ipv6); yours will probably be similar.Make sure both machines are connected to same network and firewall is not causing any issues. Try disabling the firewall with
sudo ufw disable
.And no: You don’t need to write "%eth0" after the IP address.