Hello Salem,
thank you for your reply and your suggestions, I hope that this time the indentation will not be lost, now all the code is written (end of this reply).
Originally Posted by
Salem
You need to understand that TCP connections are streams (like files or pipes). You write stuff at one end, and read it at the other.
The big problem is that you're assuming that if you write "hello" at one end, that the other end will atomically read "hello". This is simply NOT true.
It is YOUR responsibility to arrange the messages such that the receiver can reconstruct the data.
For example, every line is printable characters ending with '\n'.
The receiver then knows to call recv() in a loop until \n is received, then pass the resulting message back up the call chain.
I understand your point, but what it is still not clear to me is why at the first
Code:
if ((recv_size = recv(Soft1, server_reply, 2000, 0)) == SOCKET_ERROR)
Soft2 waits correctly while after does not stop. I can see it if I execute Soft1 in debugging mode line by line: Soft2 sends the other messages when Soft1 has not sent yet the new reply.
Soft1
Code:
#include <stdio.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[])
{
int recv_size, counter;
char server_reply[1000], server_reply2[1000];
/*Initialize Winsock*/
WSADATA wsa;
SOCKET Soft2, Soft3, new_socket;
struct sockaddr_in server, client, serverSoft3;
/*Create a TCP Socket: for server communication with Soft2 */
printf("\nInitialising Winsock");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) //MAKEWORD(2,2) parameters of WSAStartup makes a request for version 2.2 of Winsock
{
printf("Failed, error code: %d", WSAGetLastError());
return 1;
}
printf("Initialised \n");
/*Create a TCP Socket: for server communication with Soft2 */
if ((new_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) /* Look at documentation: docs.microsoft.com/en-gb/windows/desktop/api/winsock2/nf-winsock2-socket */
{
printf("Couldn't create Socket : %d", WSAGetLastError());
}
printf("Socket created \n");
//Prepare sockaddr in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(15000);
//Bind
if (bind(new_socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind Error : %d", WSAGetLastError());
}
puts("Bind ok");
//listen to incoming connection
listen(new_socket, 3);
//Accept connection
puts("Waiting for incoming connections");
int c = sizeof(struct sockaddr_in);
Soft2 = accept(new_socket, (struct sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("Accept failed : %d", WSAGetLastError());
}
puts("Connection accepted");
/*Create a TCP Socket for connecting to Soft3*/
if ((Soft3 = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) /* Look at documentation: docs.microsoft.com/en-gb/windows/desktop/api/winsock2/nf-winsock2-socket */
{
printf("Couldn't create Socket : %d", WSAGetLastError());
}
printf("Socket created \n");
/*Connect to Soft3 server*/
char address[] = "127.0.0.1";
char *addP = address;
unsigned long *p;
p = malloc(4);
inet_pton(AF_INET, addP, p);
serverSoft3.sin_addr.s_addr = *p;
serverSoft3.sin_family = AF_INET;
serverSoft3.sin_port = htons(2000);
if (connect(Soft3, (struct sockaddr *)&serverSoft3, sizeof(serverSoft3)) < 0)
{
//puts("connect error");
printf("Connect Error : %d \n", WSAGetLastError());
return 1;
}
/*Start of the while loop that receives and forwards messages*/
char Test[] = { "xxxx" };
char Mes1[] = { "Mes1" };
char Mes2[] = { "Mes2" };
char Mes3[] = { "Mes3" };
counter = 0;
while(1) {
Test[0] = 'p';
while (strcmp(Test, Mes1) != 0)
{
if ((recv_size = recv(Soft2, server_reply, 2000, 0)) == SOCKET_ERROR)
{
return 1;
}
else
{
memcpy(Test, server_reply, 4);
counter++;
printf("received message %d \n", counter);
if (send(Soft3, server_reply, strlen(server_reply), 0) < 0)
{
return 1;
}
printf("Sent message to Soft3 %d \n", counter);
if ((recv_size = recv(Soft3, server_reply2, 2000, 0)) == SOCKET_ERROR)
{
return 1;
}
printf("Received reply from Soft3 %d \n", counter);
if (send(Soft2, server_reply2, strlen(server_reply2), 0) < 0)
{
return 1;
}
printf("Sent to Soft2 reply by Soft3 %d \n", counter);
}
}
}
closesocket(Soft2);
closesocket(Soft3);
WSACleanup();
//return 1;
}
Soft2:
Code:
#include <stdio.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[])
{
/*Initialize Winsock*/
WSADATA wsa;
SOCKET Soft1;
struct sockaddr_in server;
char *message, server_reply[2000];
int recv_size;
printf("\nInitialising Winsock \n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) //MAKEWORD(2,2) parameters of WSAStartup makes a request for version 2.2 of Winsock
{
printf("Failed, error code: %d", WSAGetLastError());
return 1;
}
printf("Initialised \n");
/*Create a TCP Socket */
if ((Soft1 = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) /* Look at documentation: docs.microsoft.com/en-gb/windows/desktop/api/winsock2/nf-winsock2-socket */
{
printf("Couldn't create Socket : %d", WSAGetLastError());
}
printf("Socket created \n");
/*Connect to a server*/
char address[] = "127.0.0.1";
char *addP = address;
unsigned long *p;
p = malloc(4);
inet_pton(AF_INET, addP, p);
server.sin_addr.s_addr = *p;
server.sin_family = AF_INET;
server.sin_port = htons(15000);
if (connect(Soft1, (struct sockaddr *)&server, sizeof(server)) < 0)
{
printf("Connect Error : %d", WSAGetLastError());
return 1;
}
/*Send message 1*/
message = "Mes2 do something \n";
if (send(Soft1, message, strlen(message), 0) < 0)
{
puts("Send failed");
return 1;
}
/* Receive reply for message 1*/
/*at the following "if" Soft2 stops correctly and wait for Soft1 reply*/
if ((recv_size = recv(Soft1, server_reply, 2000, 0)) == SOCKET_ERROR)
{
puts("Reception failed0");
return 1;
}
/*Send message 2*/
message = "Mes2 do something \n";
if (send(Soft1, message, strlen(message), 0) < 0)
{
puts("Send failed");
return 1;
}
/* Receive reply for message 2*/
/*here Soft2 does not stop correctly and does not wait for Soft1 reply, as Soft2 could still read the reply from the previous message 1, and sends message 3*/
/*Soft1 then will receive message 2 and message 3 together */
if ((recv_size = recv(Soft1, server_reply, 2000, 0)) == SOCKET_ERROR)
{
puts("Reception failed0");
return 1;
}
/*Send message 3*/
message = "Mes3 do something \n";
if (send(Soft1, message, strlen(message), 0) < 0)
{
puts("Send failed");
return 1;
}
if ((recv_size = recv(Soft1, server_reply, 2000, 0)) == SOCKET_ERROR)
{
puts("Reception failed");
return 1;
}
/*Send message 4*/
message = "Mes1 stop the While loop \n";
if (send(Soft1, message, strlen(message), 0) < 0)
{
puts("Send failed");
return 1;
}
return 0;
}