Hi thanks for reviewing my question, I am trying to transfer large packets using simple UDP sockets in C. OS is windows 10; IDE Visual Studio.
System build-up:
UDP client - Send 6250 packets of 8K.
UDP server - receive 8K packets count them, and print to the screen.
When I run the server and start to receive packets, I succeed to receive between 1500-2000 packets the rest are seen in WireShark but my program lost them.
I know that it can be that the sender side is writing much faster than the server reads but it looks like a large amount of packet loss.
How can I improve or change my server-side code to be able to stand the rate?
Server code:
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
uint8_t buf[BUFLEN] = {0} //8200B buffer;
WSADATA wsa;
slen = sizeof(si_other);
int countwrite = 0;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
//Bind
if (bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
while (1)
{
printf("Waiting for data...");
fflush(stdout);
//clear the buffer by filling null, it might have previously received data
memset(buf, 0, BUFLEN);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
countwrite += 1;
printf("Packet Number : %d\n", countwrite);
}
Thank you for helping.
Related
So I have been following this guide
http://www.binarytides.com/winsock-socket-programming-tutorial/
To create a simple tcp server in c, this is the code I came up with :
https://pastebin.com/CDxiLv3b
int c;
char client_message[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Server Socket created.\n");
memset(&server_addr, 0, sizeof(server_addr));
//Prepare the sockaddr_in structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
//Bind
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
}
printf("Bind to port %d done.\n", port);
//Listen to incoming connections
listen(server_socket, 3);
//Accept and incoming connection
puts("Waiting for incoming reverse shell...");
c = sizeof(struct sockaddr_in);
while ((client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &c)) != INVALID_SOCKET)
{
puts("Connection accepted");
if ((recv_size = recv(client_socket, client_message, 2000, 0)) == SOCKET_ERROR)
{
puts("recv failed");
break;
}
client_message[recv_size] = '\0';
strcpy_s(path, MAX_PATH_LEN, client_message);
break;
}
if (client_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
return 1;
}
return 0;
(Yes I basicly copied and changed stuff)
Now the problem is that I can only connect to this server using the same connection I cant connect to it using diffrent computers in the network and even if I open port (which shouldn't actually matter) it wont accept the connection from the diffrent computers on my network (only from the same computer)
I just needed to open ports on the firewall
I want to implement a server-client monothreaded, using select();
For the server part, I took the code from http://www.binarytides.com/code-tcp-socket-server-winsock/ and for the client, the site does not provide some code, they use netcat to simulate the client. So, for the client, I am using this code:-
#include <stdio.h>
#include <winsock2.h
#pragma comment(lib,"ws2_32.lib")
int main(void) {
struct sockaddr_in si_other;
int s, slen=sizeof(si_other);
char buf[512];
char message[512];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(8888);
si_other.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//start communication
while(1)
{
printf("Enter message : ");
gets(message);
//send the message
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//receive a reply and print it
//clear the buffer by filling null, it might have previously received data
memset(buf,'\0', BUFLEN);
//try to receive some data, this is a blocking call
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts(buf);
}
closesocket(s);
WSACleanup();
return 0;
}
Even the server and the client have the same port, the client always returns -1 meaning that he don't send any message to server. Can someone please tell me what I am doing wrong here? Any tips would be appreciated.
Thanks.
I wanted to receive an *.xml data by port 3702.
So I made a example Server. And sended data by three port 1500,2500,3702.(Edit the PORT in line 43)
It worked and printed data correctly from port 1500,2500.
But when I set the PORT to 3702.
it returned me a error:**Bind failed with error code :10048**
I found that maybe it existed other Client IP were sending data by PORT 3702 in my LAN.
How can I fix it?
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define BUFLEN 8192 //Max length of buffer
#define PORT 3702 //The port on which to listen for incoming data
int main()
{
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
char buf[BUFLEN];
WSADATA wsa;
slen = sizeof(si_other);
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
//Bind
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//keep listening for data
while (1)
{
printf("Waiting for data...");
fflush(stdout);
//clear the buffer by filling null, it might have previously received data
memset(buf, '\0', BUFLEN);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
//exit(EXIT_FAILURE);
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n", buf);
//now reply the client with the same data
}
closesocket(s);
WSACleanup();
return 0;
}
This is due to Address already in use.
Typically, only one usage of each socket address (protocol/IP address/port) is permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO_REUSEADDR).
Client applications usually need not call bind at all - connect chooses an unused port automatically. When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed. This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.
SOCKET s; // Create a SOCKET for listening for
// incoming connection requests.
SOCKET new_socket; // create a socket for accepting incoming connection
uint16 port =18001;
void CreateSocket()
{
int sin_size;
WSADATA wsa;
struct sockaddr_in server, master; // creating a socket address structure: structure contains ip address and port number
printf("Initializing Winsock\n");
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0)
{
printf("Failed Error Code: %d", WSAGetLastError());
return -1;
}
printf("Initialised\n");
//CREATING a SOCKET
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
server.sin_addr.s_addr = inet_addr("192.168.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
//Binding between the socket and ip address
if(bind (s, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
puts("Bind Done");
//Listen to incoming connections
listen(s, 3);
//Accepting the incoming connection
sin_size = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr *)&master, &sin_size);
printf("\n I got a connection from (%s , %d)",
inet_ntoa(master.sin_addr),ntohs(master.sin_port));
closesocket(new_socket);
/*new_socket = accept(s, NULL, NULL);
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error: %ld\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
else
printf("Client connected.\n");*/
}
I have created the socket and accepting the connection from the master but anyone tell me the condition for checking if there is any data available on the specified port number ?? I am using windows operating system. The above code is for creating socket for windows operating system.
how to make the above code to accept port number as an argument for sending and receiving data ??
You can easily find this online.
Assuming you are using winsock API, you just need to call recvfrom() - it will either return an error if there is some problem, or it will block until there is available incoming data.
See the documentation here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740120%28v=vs.85%29.aspx
typedef unsigned int uint16;
SOCKET s, new_socket;
uint16 port =18001;
void CreateSocket()
{
WSADATA wsa;
struct sockaddr_in server; // creating a socket address structure: structure contains ip address and port number
printf("Initializing Winsock\n");
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0)
{
printf("Failed Error Code: %d", WSAGetLastError());
return -1;
}
printf("Initialised\n");
//CREATING a SOCKET
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
server.sin_addr.s_addr = inet_addr("192.168.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
//Binding between the socket and ip address
if(bind (s, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
puts("Bind Done");
//Listen to incoming connections
listen(s, 3);
//Accepting the incoming connection
new_socket = accept(s, NULL, NULL);
if (new_socket == INVALID_SOCKET)
{
printf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
else
printf("Client connected.\n");
closesocket(s);
}
int main()
{
CreateSocket();
return 0;
}
this is for TCP.
I am receiving a connection from the MASTER via the above ip address and port number, So I created a socket with port number and ip address for it. But how to check that the socket is active ?? how to check that the above socket code is valid (it's not showing any error). I am getting an error on the MASTER side saying that :
CONNECT EVENT CHECK FAILED (WSAGetLastError())
Could anyone help me in this ??
There is no connection between your socket and the address, you never bind() the address in server to the socket s.
Which, of course, is why your client fails to connect since the socket will not be using the expected port. I assume that you elsewhere call accept() and so on, to actually make the socket accept incoming connections, too.