I try to send a file data size of around 100MB from the client to the server in UDP ipv6.
the server I think it works well but the client I cannot figure out why I cannot send the file.
When I try to "sendto" I got the message: perror("[-]Error in sending the file. in UDP CLIENT")"
here is my code:
void client() {
int sockfd;
char buffer[65536];
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(P);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
FILE *fp = fopen("data.txt","r");
char data[SIZE] = {0};
while (fgets(data, SIZE, fp) != NULL) {
if (sendto(sockfd, data, sizeof(data),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr)) == -1) {
perror("[-]Error in sending file. in UDP CLIENT");
exit(1);
}
bzero(data, SIZE);
}
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *) buffer, 65536,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
}
Related
I try to make a Socket client/server bundle running at the same time, passing information to one another. The problem is, after sending the first piece of data from the client, the server returns the answer correctly but becomes stuck on the call to function send(), disabling the ability for the server to receive another data from the client.
I use the following pieces of code in server and client:
Client Code
char requestToSend[1000] = "Some request";
int client_socket;
struct sockaddr_in servaddr;
client_socket = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
connect(client_socket, (SA*)&servaddr, sizeof(servaddr));
char buffer[MAX];
bzero(buffer, sizeof(buffer));
send(server_socket, requestToSend, sizeof(requestToSend), 0);
bzero(requestToSend, sizeof(requestToSend));
while (strcmp(requestToSend, "") == 0) {
recv(server_socket, requestToSend, sizeof(requestToSend), 0);
}
shutdown(client_socket, SHUT_RDWR);
printf("Received: %s", requestToSend); // requestToSend is not the received result!
Server Code
The following code should return "My new result" in response to any request from the client.
while (1) {
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, sizeof(buffer), 0);
shutdown(server_socket, SHUT_RDWR);
}
There are other questions on Stack Overflow mentioning the problem of send() being stuck, but they don't provide an answer to this question.
You should only open and bind the server socket once. The loop should start before the accept() call. And you should close the client socket, not just call shutdown().
When you're sending the reply, you should just send strlen(buffer)+1 bytes, not sizeof(buffer). The latter will send MAX bytes, which will include lots of uninitialized bytes. Adding 1 to strlen() will include the null byte.
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
while (1) {
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, strlen(buffer)+1, 0);
close(client_socket);
}
The client's recv() loop should loop until it receives 0, which indicates that the server has closed the socket. Each call should append to the buffer, not overwrite it.
char *ptr = requestToSend;
size_t len = sizeof(requestToSend);
int nread;
while ((nread = recv(server_socket, ptr, len, 0)) != 0) {
if (nread < 0) {
perror("recv from server");
exit(1);
}
ptr += nread;
len -= nread;
}
And it should also close the socket, not use shutdown(). shutdown() is generally only used when you want to half-close a socket -- you want to send EOF to the other system, but continue to read its responses.
Hello I'm sending requests in cycle and then processing them, I have to make that until the program's not stopped by the user. I have to use UDP and after testing on localhost after 1020 requests I get error in gethostbyname, it returns NULL
int sockfd, portno, n, serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
portno = my_port;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
server = gethostbyname(my_host);
bzero(buf, BUFSIZE);
if (sockfd < 0) {
error("ERROR opening socket");
}
if (server == NULL) {
fprintf(stderr,"ERROR, no such host as %s\n", my_host);
exit(0);
}
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
serverlen = sizeof(serveraddr);
n = sendto(sockfd, packet, myArraySize, 0, (struct sockaddr *)&serveraddr, serverlen);
if (n < 0) {
error("ERROR in sendto");
}
n = recvfrom(sockfd, buf, BUFSIZE, 0, (struct sockaddr *)&serveraddr, &serverlen);
if (n < 0) {
error("ERROR in recvfrom");
}
I found nothing about this behavior, and if I'm not using the localhost then I get the error after just 120 requests.
Most likely explanation is that each process on your system is only allowed to have 1024 open file descriptors at a time. 3 of those are reserved for stdin, stdout and stderr.
So the problem is that each time you call gethostbyname, you create a new sockfd, but the code doesn't close the socket when it's done with it.
This is a simple iterative client-server program. Where the server prints out "Received request" on successful establishment of connection.
server side
#define LENGTH 256
#define SERV_PORT 4000
#define LISTENQ 8
int main()
{
int listenfd, connfd, n;
socklen_t clilen;
char buf[LENGTH];
struct sockaddr_in cliaddr, servaddr;
//creation of socket
listenfd = socket (AF_INET, SOCK_STREAM, 0);
//creating socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// printf("\nServer running.. waiting for connections");
// listen(listenfd, LISTENQ);
for(; ;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("\nReceived request");
//sleep(5);
}
return 0;
}
client side
#define LENGTH 256
#define SERV_PORT 4000
int main( int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[256];
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket failed");
exit(1);
}
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]);
if(hp == 0)
{
perror("gethost by name failed");
exit(1);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(4000);
if(connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("\nconnect failed");
exit(1);
}
return 0;
}
When I run this multiple client-server code, the output for first client is different from the preceding clients. I need the first client to output like others. Can someone help?
When the first client establishes a connection with the server, the server doesn't output "Received request", where as, for the other clients do output "Received request".
You need to restore the listen() call. – EJP
I created a server socket in C. This is the most basic stuff like what you would fine in a simple TCP server example. Server code is below. I also created a client socket that runs on the host machine. Code also below. However, for some reason the client is not able to connect to the server. The IP address I used is the same as the one under the entry eth0 from the "ip addr" command. The network adapter of the VM is a bridged connection.
The exact same code works when both client and server run on the same machine (the host).
Thank you!
Server code:
int sockfd;
int clientfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return EXIT_FAILURE;
}
printf("Socket descriptor is: %d\n", sockfd);
memset(&self, 0, sizeof (self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*) &self, sizeof (self)) != 0) {
perror("socket--bind");
return EXIT_FAILURE;
}
if (listen(sockfd, 20) != 0) {
perror("socket--listen");
return EXIT_FAILURE;
}
clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
Client Code:
int sock;
struct sockaddr_in server;
//struct sockaddr_in client;
struct hostent *hp;
//char buf[BUFFER_SIZE];
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die(6, "Opening stream socket");
printf("Client socket file descriptor is: %d\n", sock);
memset(&server, (char) 0, sizeof (server));
server.sin_family = AF_INET;
hp = gethostbyname(host_name);
if (!hp) {
//sprintf(buf, "%s: unknown host\n", host_name);
die(8, "%s: unknown host\n", host_name);
}
memcpy(hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons((u_short) SERVER_PORT);
/* Try to connect */
if ((connect(sock, (struct sockaddr *) &server, sizeof (server))) < 0)
die(7, "%s", "Failed to connect stream socket\n");
I'm trying to make a program (client) which kan send a message to a server upon request from user. Stripped down code follows:
Client:
int main(int argc, char **argv) {
struct sockaddr_in servaddr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6789);
servaddr.sin_addr.s_addr = inet_addr(<ip_address_of_server>);
while(1) {
char message[161];
fgets(message, 161, stdin);
/* Replacing '\n' with '\0' */
char *tmp = strchr(message, '\n');
if (tmp) *tmp = '\0';
connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
send(sock, message, strlen(message), 0);
close(sock);
}
}
Server:
int main(int argc, char **argv) {
struct sockaddr_in servaddr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6789);
bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(sock, 5);
while(1) {
int clisock = accept(sock, (struct sockaddr *) NULL, NULL);
if (clisock >= 0) {
int messageLength = 160;
char message[messageLength+1];
int in, index = 0, limit = messageLength;
while ((in = recv(clisock, &message[index], messageLength, 0)) > 0) {
index += in;
limit -= in;
}
printf("%s\n", message);
}
close(clisock);
}
}
Now, this works for the first message I send. But then it is not able to make another connection (I get the error message "Bad file descriptor" when trying to connect in the Client program.) Can anyone see what I have misunderstood? Thank you :)
your client programme also does the same mistake, first time you open the socket but after the first connection is done you close the socket, so the next time in the loop the socket descriptor is not valid, you need to re-open the socket but that's missing, please remove the socket call from top and add the below line in the start of while loop
int sock = socket(AF_INET, SOCK_STREAM, 0);
The problem is that you're closing the listening socket sock, instead of the client socket clisock.
servaddr.sin_addr.s_addr = inet_addr(<ip_address_of_server>);
instead of the above lines in your client code use the following
inet_pton(AF_INET,"<ipofserver>",&servaddr.sin_addr);
perform an error check for the fllowing function also.