C socket programming: recv always fail - c

i'm trying to understand C socket programming for an university exam.
I made this simple example:
socket_server.c
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SA struct sockaddr
#define MAX_MESS_LEN 16
int main(){
struct sockaddr_in my_addr, cl_addr;
int ret, len, sk, cn_sk;
char cl_ip[INET_ADDRSTRLEN + 1], msg[MAX_MESS_LEN + 1];
sk = socket(AF_INET, SOCK_STREAM, 0); //creo socket TCP/IPv4 listener
printf("socket created! :)\n");
memset(&my_addr, 0, sizeof(my_addr)); //azzero struttura my_addr
my_addr.sin_family = AF_INET; //famiglia protocolli IPv4
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //in ascolto su qualsiasi interfaccia
my_addr.sin_port = htons(1234); //porta del socket
ret = bind(sk, (SA *) &my_addr, sizeof(my_addr)); //lego il socket alla struttura indirizzo
printf("socket binded! :)\n");
ret = listen(sk, 10); //mi pongo in ascolto sul socket con massimo 10 richieste pendenti
printf("socket listening (on any interface with port 1234)! :)\n");
len = sizeof(cl_addr);
printf("socket is going to wait for a request... zzzzZZZ\n");
cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista
printf("socket accepted request! :D\n");
inet_ntop(AF_INET, &cl_addr.sin_addr, cl_ip, INET_ADDRSTRLEN); //converto indirizzo IPv4 cl_addr.sin_addr in stringa (cl_ip)
printf("IP client: %s\n", cl_ip);
ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //attendo la ricezione di tutti i caratteri della stringa inviata sul socket dal client
msg[MAX_MESS_LEN + 1] = '\0';
printf("received data (%d bytes): %s\n", ret, msg);
if(ret == -1 || ret < MAX_MESS_LEN)
printf("recv ERROR! :(\n");
close(sk); //chiudo il server
}
socket_client.c
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#define SA struct sockaddr
#define MSG_LEN 17
int main(){
struct sockaddr_in srv_addr;
int ret, sk;
char msg[MSG_LEN];
sk = socket(AF_INET, SOCK_STREAM, 0);
printf("Socket created! :)\n");
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sin_family = AF_INET;
srv_addr.sin_port = htons(1234);
ret = inet_pton(AF_INET, "192.168.1.132", &srv_addr.sin_addr);
printf("Trying to establish a connection with 192.168.1.132 on port 1234...");
ret = connect(sk, (SA *) &srv_addr, sizeof(srv_addr)); //faccio una richiesta sul socket
if(ret != -1) printf("Connection established! :D\n");
else printf(" connection error :(\n");
strcpy(msg, "something to send"); //scrivo messaggio in una stringa
printf("sending message: %s\n", msg);
ret = send(sk, (void *) msg, strlen(msg), 0); //invio il messaggio sul socket
if(ret == -1 || ret < strlen(msg))
printf("send ERROR! :(\n");
close(sk);
}
And compiled it with:
gcc socket_client.c -o socket_client
gcc socket_server.c -o socket_server
Maybe it's a stupid question but the recv function in server always fail, there is an example output:
Server:
socket created! :)
socket binded! :)
socket listening (on any interface with port 1234)! :)
socket is going to wait for a request... zzzzZZZ
socket accepted request! :D
IP client: 192.168.1.132
received data (-1 bytes): ����
recv ERROR! :(
Client:
Socket created! :)
Trying to establish a connection with 192.168.1.132 on port 1234...Connection established! :D
sending message: something to send
What's the problem? I don't get it! :( I followed step by step, my teacher's guide.
I'm running on arch linux 64 bit ;)
Thank you for response!

cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista
...
ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //at
You don't recv on the connected socket cn_sk to the client, but instead on the listener socket sk. If you would check the errno you would probably see ENOTCONN.

Related

Is it possible to launch multiple servers listening to a different IP socket address?

I'm trying to launch multiple servers, at once, in a c program. For the sake of simplicity let's say 5 servers.
If I understand well the sockets, each of them must be listening to a different IP socket address (different PORT, different IP interface address).
I thought to do that inside a loop, incrementing port number by i at each turn. Here's my current code just to launch one server. I know it's possible with bash by launching the same process in background, but in C I really don't know how to do that and if it's even possible
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
long PORT;
int main(int argc, char const *argv[])
{
/* 1. Open a socket
2. Bind to a address(and port).
3. Listen for incoming connections.
4. Accept connections
5. Read/Send
*/
int listenerSocket; /* socket for accepting connections */
int clientSocket; /* socket connected to client */
struct sockaddr_in server;
struct sockaddr_in client; /* client address information */
char buf[100]; /* buffer for sending & receiving data */
int errnum;
listenerSocket = socket(AF_INET, SOCK_STREAM, 0);
if(listenerSocket == -1){
perror("erreur lors de la création du socket");
}
PORT = strtol(argv[1], NULL, 10);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port= htons(PORT);
if (bind(listenerSocket, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
puts("Server waiting for connection...");
while(1){
if (listen(listenerSocket, 5) < 0){
perror("listen failed");
exit(EXIT_FAILURE);
}
int c = sizeof(client);
if((clientSocket = accept(listenerSocket, (struct sockaddr*) &client, &c)) < 0){
puts("error accepting the request");
perror("Accept()");
}
puts("connection accepted");
while(1){
if( recv(clientSocket, buf, sizeof(buf), 0) < 0) {
errnum = errno;
perror("Recv()");
printf("val printed by errno: %d\n",errno);
}
printf("Message : %s\n", buf);
}
if (send(clientSocket, buf, sizeof(buf), 0) < 0)
{
perror("Send()");
exit(7);
}
close(clientSocket);
close(listenerSocket);
printf("Server ended successfully\n");
exit(0);
}

(Socket operation on non socket) error while trying to receive data on a TCP server

What I want to do is send a message (which I type on the terminal) from the client to the server.
I'm getting this error on the server when I try to call the recv() function. As you can see, the client doesn't show errors.
This is the code I've written for the server side:
#define BUFFERLEN 1024
int main(int argc, char **argv)
{
char name[BUFFERLEN];
int sockfd_serv, sockfd_cli, port;
struct sockaddr_in server_addr, client_addr;
sockfd_serv = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd_serv == -1)
{
perror("Error abriendo el socket");
exit(1);
}
bzero((char *)&server_addr, sizeof(server_addr));
port = atoi(argv[1]);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
//Asignamos un puerto al socket
if (bind(sockfd_serv, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("Error al asociar el puerto a la conexión");
close(sockfd_serv);
return 1;
}
//Ponemos el servidor a escuchar
listen(sockfd_serv, 5);
printf("Escuchando en el puerto %d\n\n", ntohs(server_addr.sin_port));
while (1)
{
int long_cli = sizeof(client_addr);
//Aceptamos la conexión de un cliente
if (accept(sockfd_serv, (struct sockaddr *)&client_addr, &long_cli) == -1)
{
perror("Error al aceptar conexión");
close(sockfd_serv);
return 1;
}
printf("Conectado con %s:%d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));
int nombre = recv(sockfd_cli, &name, BUFFERLEN, 0);
if (nombre == -1)
{
perror("Name error");
return 1;
}
printf("%s", name);
}
return 0;
}
I'm confused because I'm already checking that the socket is created properly. What does "non-socket" refers to?
You never initialize sockfd_cli. Odds are, it's zero, and that's your standard input terminal and not a socket. You need to store the return value from accept in sockfd_cli.

Sending/receiving strings with sockets

Here's a simple code tcp client/server where the server sends "Hello from Server" after connection established. My problems are:
1) client writes the string after i close the server.exe window and don't know why;
2) client prints strange characters and not "Hello from server". I miss something in the output format.
SERVER
#if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define PROTOPORT 5193 //default protocol port number
#define QLEN 6 // size of request queue
#define BUFFERSIZE 10
void ErrorHandler (char *errorMessage) {
printf (errorMessage);
}
void ClearWinSock() {
#if defined WIN32
WSACleanup ();
#endif
}
int main(void) {
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup (MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
ErrorHandler ("Error at WSAStartup()\n");
return 0;
}
#endif
// CREAZIONE DELLA SOCKET
int MySocket;
MySocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MySocket < 0) {
ErrorHandler ("socket creation failed.\n");
ClearWinSock();
return 0;
}
// ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
struct sockaddr_in sad;
memset (&sad, 0, sizeof (sad)); //ensures that extra bytes contain 0
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr ("127.0.0.1"); //ip del server con conversione
//da notazione dotted-decimal in un numero a 32 bit
//espresso nella rappresentazione della rete
sad.sin_port = htons (5193); //host to network short
//Assegnazione porta e ip alla socket e verifica presenza di eventuali errori
if (bind (MySocket, (struct sockaddr*) & sad, sizeof (sad)) < 0) {
ErrorHandler ("bind() failed.\n");
closesocket (MySocket);
ClearWinSock ();
return 0;
}
// SETTAGGIO DELLA SOCKET ALL'ASCOLTO
if (listen (MySocket, QLEN) < 0) {
ErrorHandler ("listen() failed.\n");
closesocket (MySocket);
ClearWinSock ();
return 0;
}
// ACCETTARE UNA NUOVA CONNESSIONE - e creazione di una nuova socket per comunicare con il client
struct sockaddr_in cad; //structure for the client address
int clientSocket; // socket descriptor for the client
int clientLen; //the size of the client address
printf ("Waiting for a client to connect...");
while (1) {
clientLen = sizeof (cad); //set the size of the client address
if ((clientSocket = accept (MySocket, (struct sockaddr*) &cad, &clientLen)) < 0) {
ErrorHandler ("accept() failed.\n");
// CHIUSURA DELLA CONNESSIONE
closesocket (MySocket);
ClearWinSock ();
return 0;
}
printf ("Handling client %s\n", inet_ntoa (cad.sin_addr));
}
char* inputString = "Hello from server"; // Stringa da inviare
int stringLen = strlen (inputString); // Determina la lunghezza
// INVIARE DATI AL CLIENT
if (send (clientSocket, inputString, stringLen, 0) != stringLen) {
ErrorHandler ("send () sent a different number of bytes than expected");
closesocket (clientSocket);
ClearWinSock();
system("pause");
return 0;
}
closesocket(MySocket);
ClearWinSock ();
return 0;
}
CLIENT
#if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define BUFFERSIZE 20 // Dimensione buffer che riceve dati dal server
#define PROTOPORT 5193 // Numero di porta di default
void ErrorHandler (char *errorMessage) {
printf (errorMessage);
}
void ClearWinSock () {
#if defined WIN32
WSACleanup();
#endif
}
int main (void) {
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup (MAKEWORD (2,2), &wsaData);
if (iResult !=0) {
printf ("error at WSASturtup\n");
return 0;
}
#endif
// CREAZIONE DELLA SOCKET
int Csocket;
Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Csocket < 0) {
ErrorHandler ("socket creation failed.\n");
closesocket (Csocket);
ClearWinSock ();
return 0;
}
// COSTRUZIONE DELL'INDIRIZZO DEL SERVER
struct sockaddr_in sad;
memset (&sad, 0, sizeof (sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr ("127.0.0.1"); //ip del server con conversione
//da notazione dotted-decimal in un numero a 32 bit
//espresso nella rappresentazione della rete
sad.sin_port = htons (5193); // Server port
//CONNESSIONE AL SERVER
if (connect (Csocket, (struct sockaddr*) &sad, sizeof (sad)) < 0) {
ErrorHandler ("Failed to connect.\n");
closesocket (Csocket);
ClearWinSock();
return 0;
}
char buf[BUFFERSIZE];
recv (Csocket, buf, BUFFERSIZE - 1, 0);
printf("Server scrive: %s\n",buf);
// CHIUSURA DELLA CONNESSIONE
closesocket (Csocket);
ClearWinSock();
printf ("\n");
system ("pause");
return 0;
}
In the end: If I would to send more strings, have I to use one send() and one recv() for each of them?
The biggest issue is that you do not break out of the server loop. This is why you don't see anything on the client until you quit the server. The socket gets closed when the program terminates, so the recv call in client no longer blocks. Also, in client you don't check return val from recv and print junk.
Server fix:
while (1) {
clientLen = sizeof (cad); //set the size of the client address
if ((clientSocket = accept (MySocket, (struct sockaddr*) &cad, &clientLen)) < 0) {
....
}
printf ("Handling client %s\n", inet_ntoa (cad.sin_addr));
break; // <- terminate loop,
// or just get rid of the loop altogether as there
// is no real need for it I can see
}
Client fix:
int read = recv (Csocket, buf, BUFFERSIZE - 1, 0);
if (read <= 0) {
// Not successful
}
else {
buf[read] = 0; // Add eos
printf("%s", buf);
}

Winsock echo server port

I'm trying to port this simple TCP echo program (https://github.com/mafintosh/echo-servers.c/blob/master/tcp-echo-server.c) under Windows for teaching purposes.
My adaptation compiles and run, but it doesn't work:
**** EDIT: The listen call was somehow cut out. Thank to Remy ****
The client connects, but doen't get any echo.
Ported code is as follows (error messages are in Italian, but they should be clear nevertheless):
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#define BUFFER_SIZE 1024
void on_error(char *s) { fprintf(stderr,"%s\n",s); fflush(stderr); exit(1); }
int main(int argc, char *argv[]) {
WSADATA wsadata;
int server_fd, client_fd, err;
struct sockaddr_in server, client;
char buf[BUFFER_SIZE];
int port = 6666;
int risultato = WSAStartup(MAKEWORD(2,2),&wsadata);
if (risultato != NO_ERROR)
{fprintf(stderr,"Errore in WSAStartup");fflush(stderr); exit(1);}
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) on_error("Non ho potuto creare il socket\n");
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
const char opt_val = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof opt_val);
/** bind & listen **/
err = bind(server_fd, (struct sockaddr *) &server, sizeof(server));
if (err < 0) on_error("Non ho potuto fare il bind del socket\n");
err = listen(server_fd, 128);
if (err < 0) on_error("Non ho potuto mettermi in ascolto sul socket\n");
printf("SERVER LISTENING ON PORT %d\n", port);
while (1) {
int client_len = sizeof(client);
do {
client_fd = accept(server_fd, (struct sockaddr *) &client, &client_len);
} while ( client_fd = SOCKET_ERROR);
if (client_fd < 0) on_error("Non riesco a stabilire una nuova connessione\n");
while (1) {
int read = recv(client_fd, buf, BUFFER_SIZE, 0);
if (!read) break;
if (read < 0) on_error("Errore nella lettura dal client\n");
err = send(client_fd, buf, read, 0);
if (err < 0) on_error("Errore nella scrittura verso il client\n");
}
}
WSACleanup();
return 0;
}
You are calling bind() to set up the listening port, but you are not calling listen() to actually start listening on the port before entering your accept() loop.
Once you fix that mistake, your accept() loop is broken anyway because it is forcing client_fd to SOCKET_ERROR even if accept() is successful. Your while() condition is using the = assignment operator when it needs to use the == comparison operator instead. And you should be checking for INVALID_SOCKET instead of SOCKET_ERROR.
Now with that said, there are some other things to consider:
WinSock does not use int to represent sockets, it uses SOCKET instead, which is a UINT_PTR. When checking for an invalid socket handle, don't use < 0, use == INVALID_SOCKET instead.
Most socket functions return error codes via WSAGetLastError() (WSAStartup() being an exception to that). Get in the habit of using it, and reporting error codes in your output messages, so you know why things are failing.
SO_REUSEADDR expects a BOOL value, not a char value. A BOOL is a typedef for int and thus is 4 bytes.
not all socket errors are fatal, so you should not kill your entire server if a recv()/send() operation fails on a non-fatal error.
send() is not guaranteed to send everything you ask it to send, so you should account for that.
don't forget to close the accepted client socket when you are done using it.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#define BUFFER_SIZE 1024
void on_error(char *s, int *errCode = NULL)
{
int err = (errCode) ? *errCode : WSAGetLastError();
fprintf(stderr, "%s: %d\n", s, err);
fflush(stderr);
exit(1);
}
int main(int argc, char *argv[])
{
WSADATA wsadata;
SOCKET server_fd, client_fd;
struct sockaddr_in server, client;
int port = 6666, err;
char buf[BUFFER_SIZE];
err = WSAStartup(MAKEWORD(2,2), &wsadata);
if (err != 0)
on_error("Errore in WSAStartup", &err);
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == INVALID_SOCKET)
on_error("Non ho potuto creare il socket");
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
/** bind & listen **/
const BOOL opt_val = TRUE;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&opt_val, sizeof(opt_val));
err = bind(server_fd, (struct sockaddr *) &server, sizeof(server));
if (err == SOCKET_ERROR)
on_error("Non ho potuto fare il bind del socket");
err = listen(server_fd, 1);
if (err == SOCKET_ERROR)
on_error("Non ho potuto mettermi in ascolto sul socket");
printf("SERVER LISTENING ON PORT %d\n", port);
while (1)
{
int client_len = sizeof(client);
client_fd = accept(server_fd, (struct sockaddr *) &client, &client_len);
if (client_fd == INVALID_SOCKET)
on_error("Non riesco a stabilire una nuova connessione");
bool keepLooping = true;
do
{
int read = recv(client_fd, buf, BUFFER_SIZE, 0);
if (read == 0)
break;
if (read == SOCKET_ERROR)
{
err = WSAGetLastError();
if ((err != WSAENOTCONN) && (err != WSAECONNABORTED) && (err == WSAECONNRESET))
on_error("Errore nella lettura dal client", &err);
break;
}
char *pbuf = buf;
do
{
int sent = send(client_fd, pbuf, read, 0);
if (sent == SOCKET_ERROR)
{
err = WSAGetLastError();
if ((err != WSAENOTCONN) && (err != WSAECONNABORTED) && (err == WSAECONNRESET))
on_error("Errore nella scrittura verso il client", &err);
keepLooping = false;
break;
}
pbuf += sent;
read -= sent;
}
while (read > 0);
}
while (keepLooping);
closesocket(client_fd);
}
WSACleanup();
return 0;
}
I'm sorry, but
while (client_fd = SOCKET_ERROR)
don't you mean?
(client_fd == SOCKET_ERROR)

Retrieving data from a socket client-server transaction

I am emulating a client-server socket transaction. Suppose, the client sent some ip packet with
status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
where sock is the socket, packet points to an ip packet (with ip header struct iphdr and tcp header struct tcphdr)
Now, on the server side, I want to use some function that retrieves the data in packet and displays it. The connection between client and server is correctly set up but when trying to use the recv function, I don't get any data. Is recv the right function
So on the client side I have
packet = malloc(sizeof(struct iphdr)+ sizeof(struct tcphdr));
and I use
send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
on the server side, I declared some char packet[32]; and I used this
recv(sock, packet, 32, 0);
Edit 2 - here's the code
On the client side
Edit on the client side (to shorten, I didn't mention the included libraries, the struct iphdr, tcphdr, the in_chksum function, as well I didn't hydrate the tcp header, for now I just want to test)
struct tcphdr tcp_hdr;
struct ip ip_hdr;
#define PORT 23
int sendmeifyoucan(SOCKET sock, SOCKADDR_IN * sin , int size ){
struct ip * ip = (struct ip *)malloc(sizeof(struct ip));
struct tcphdr * tcp;
char * packet;
int sock_err;
int psize=0, status = 1;
packet = malloc(sizeof(struct ip)+ sizeof(struct tcphdr));
memset(packet, 0, sizeof(struct ip) + sizeof(struct tcphdr));
ip->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + psize);
ip->ip_hl = 5;
ip->ip_v = 4;
ip->ip_ttl = 255;
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_p = IPPROTO_ICMP;
ip->ip_src.s_addr = inet_addr("127.0.0.1");
ip->ip_dst.s_addr = inet_addr("127.0.0.1");
ip->ip_sum = in_chksum((u_short *)ip, sizeof(struct ip));
status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
free(packet);
return 0;
}
int main(void)
{
int erreur = 0;
SOCKADDR_IN sin;
SOCKET sock;
SOCKADDR_IN csin;
SOCKET csock;
int sock_err;
if(!erreur)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock != INVALID_SOCKET)
{
printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
int size = 0;
/* Configuration */
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
sendmeifyoucan(sock, &sin,size);
/* Si l'on reçoit des informations : on les affiche à l'écran */
}
}
printf("Fermeture de la socket client\n");
closesocket(csock);
printf("Fermeture de la socket serveur\n");
closesocket(sock);
printf("Fermeture du serveur terminée\n");
}
else
perror("socket");
}
return EXIT_SUCCESS;
}
On the server side
#define PORT 23
int main(void)
{
int erreur = 0;
SOCKET sock;
SOCKADDR_IN sin;
socklen_t recsize = sizeof(sin);
SOCKADDR_IN csin;
char buffer[32] = "";
int sock_err;
if(!erreur)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock != INVALID_SOCKET)
{
printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
/* Configuration */
csin.sin_addr.s_addr = inet_addr("127.0.0.1");
csin.sin_family = AF_INET;
csin.sin_port = htons(PORT);
sock_err = bind(sock, (SOCKADDR*) &csin, sizeof(csin));
if(sock_err != SOCKET_ERROR)
{
sock_err = listen(sock, 5);
printf("Listage du port %d...\n", PORT);
}
if(sock_err != SOCKET_ERROR)
{
/* Attente pendant laquelle le client se connecte */
printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);
sock = accept(sock, (SOCKADDR*)&sin, &recsize);
}
if(recv(sock, buffer, 32, 0) != SOCKET_ERROR)
{
printf("Recu : %s\n", buffer);
}
else
{
printf("Impossible de se connecter\n");
}
closesocket(sock);
}
else
perror("socket");
}
return EXIT_SUCCESS;
}
Edit 3 - the headers
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#include <stdio.h>
#include <stdlib.h>
#define PORT 23
Okay now I see your problems.
On client side:
First issue (big):
You are not CONNECTING at all.
where is your connect() call on the client side?
If you want to use SOCK_STREAM you need a connect(2) call
In the code snippet:
if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) {
printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
/* Si l'on reçoit des informations : on les affiche à l'écran */
}
your sendmeifyoucan() is OUTSIDE the if block { } ;
2nd issue
struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr *));
should be
struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr));
Otherwise you are in a stack overflow issue.
Third issue (not so big)
you are allocating char *packet but you are not copying anything on to it it's just memset to 0;
Debug accordingly and try again :)

Resources