I'm trying to send a packet through UDP, however I'm getting a seg fault on line 198:
sendto(socketfd, buffer_str, total_len, 0, res->ai_addr, res->ai_addrlen);
And I'm not quite sure what is causing it. I've run the program through GDB, and none of the arguments seem to have anything wrong with them. the file I'm attempting to send is just a simple txt file which has the text "Lorem ipsum dolor sit amet" in it.
The first sendto on line 76 works absolutely fine, as does the recv from on line 78. When I tried replacing the sendto on 198 with the code from like 76, I got the same segfault.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
struct packet {
unsigned int total_frag;
unsigned int frag_no;
unsigned int size;
char* filename;
char filedata[1000];
};
struct node {
struct node* next;
struct packet data;
};
struct list {
struct node* head;
};
int main(int argc, char *argv[]) {
printf("ftp <file name>\n");
struct sockaddr_storage their_addr;
socklen_t addr_size = sizeof(their_addr);
struct addrinfo hints, *res;
char* port = "5050";//argv[2];
struct sockaddr_in *serverAddr;
serverAddr = malloc(sizeof(struct sockaddr_in));
memset(&hints, 0, sizeof(hints));
memset(serverAddr, 0, sizeof(*serverAddr));
serverAddr->sin_family = AF_INET;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_addr = (struct sockaddr *) serverAddr;
getaddrinfo("ug168.eecg.utoronto.ca"/*argv[1]*/, port, &hints, &res);
int socketfd = socket(PF_INET, SOCK_DGRAM, 0);
char fileName[100];
scanf("%s", fileName);
int fd = open(fileName, O_RDWR);
if(fd == -1) {
return 0;
}
struct timeval pre_time, post_time;
gettimeofday(&pre_time, NULL);
sendto(socketfd, (char*)"ftp", 3, 0, res->ai_addr, res->ai_addrlen);
char buf[1000];
int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)&serverAddr, &addr_size);
gettimeofday(&post_time, NULL);
buf[length] = '\0';
if(strcmp("yes", buf) == 0) {
printf("A file transfer can start\n");
}
printf("seconds : %ld\nmicro seconds : %ld\n", post_time.tv_sec - pre_time.tv_sec, post_time.tv_usec - pre_time.tv_usec);
FILE *file;
file = fopen(fileName, "rb"); //rb = read as binary
fseek(file, 0, SEEK_END);
int fileLength = ftell(file);
fseek(file, 0, SEEK_SET);
char buffer[fileLength];
fread(buffer, fileLength, 1, file);
fclose(file);
int frag_total = fileLength / 1000;
if(fileLength % 1000 != 0) {
frag_total++;
}
struct list packet_list;
packet_list.head = malloc(sizeof(struct node));
struct node* curr = packet_list.head;
for(int i = 0; i < frag_total; i++) {
curr->data.total_frag = frag_total;
curr->data.frag_no = i + 1;
if(i == frag_total - 1) {
curr->data.size = fileLength % 1000;
} else {
curr->data.size = 1000;
}
curr->data.filename = malloc(sizeof(char) * (strlen(fileName) + 1));
strcpy(curr->data.filename, fileName);
if(i == frag_total - 1) {
//copy data equal to remainder
for(int j = 0; j < fileLength % 1000; j++) {
curr->data.filedata[j] = buffer[1000 * i + j];
}
} else {
//copy 1000 bytes
for(int j = 0; j < 1000; j++) {
curr->data.filedata[j] = buffer[1000 * i + j];
}
}
if(i < frag_total - 1) {
curr->next = malloc(sizeof(struct node));
curr = curr->next;
}
}
curr = packet_list.head;
while(curr != NULL) {
int j = curr->data.total_frag;
int frag_total_len = 0;
while(j != 0) {
j /= 10;
frag_total_len++;
}
j = curr->data.frag_no;
int frag_no_len = 0;
while(j != 0) {
j /= 10;
frag_no_len++;
}
j = curr->data.size;
int size_len = 0;
while(j != 0) {
j /= 10;
size_len++;
}
int name_len = strlen(curr->data.filename);
int total_len = frag_total_len + frag_no_len + size_len + name_len + 4 + curr->data.size; //4 bc 4 colons
char buffer_str[total_len];
j = 0;
char strbuf[total_len];
sprintf(strbuf, "%d", curr->data.total_frag);
for(int k = j; k < j + frag_total_len; k++) {
buffer_str[k] = strbuf[k-j];
}
j += frag_total_len;
buffer_str[j] = ':';
j++;
sprintf(strbuf, "%d", curr->data.frag_no);
for(int k = j; k < j + frag_no_len; k++) {
buffer_str[k] = strbuf[k-j];
}
j += frag_no_len;
buffer_str[j] = ':';
j++;
sprintf(strbuf, "%d", curr->data.size);
for(int k = j; k < j + size_len; k++) {
buffer_str[k] = strbuf[k-j];
}
j += size_len;
buffer_str[j] = ':';
j++;
for(int k = 0 ; k < name_len; k++, j++) {
buffer_str[j] = curr->data.filename[k];
}
buffer_str[j] = ':';
j++;
for(int k = 0; k < curr->data.size; k++, j++) {
buffer_str[j] = curr->data.filedata[k];
}
sendto(socketfd, buffer_str, total_len, 0, res->ai_addr, res->ai_addrlen);
curr = curr->next;
}
return 0;
}
I'm not really sure what could be causing this
The local variable res is overwritten by the call
int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)&serverAddr, &addr_size);
this is because the address of the pointer serverAddr is passed instead of the value of the pointer:
int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)serverAddr, &addr_size);
You'll probably see that the program now segfaults for another reason: The buffer handling fails for short files with less than two fragments, because curr->next is uninitialized.
The original posted code omitted error checking for getaddrinfo(), which is returning an error code and left res unchanged; that led to an uninitialized pointer being dereferenced when calling sendto(); example revision:
int rv = getaddrinfo("ug168.eecg.utoronto.ca"/*argv[1]*/, port, &hints, &res);
if (rv) {
fprintf(stderr, "getaddrinfo error, rv %d\n", rv);
return (1);
}
Related
I'm coding udp server, which can listen multiple ports. As the method of paralleling I use function poll(). So server get two ports in argc, and then try to listen the range of ports. Then open msg.txt, where saves all the information, which he get from clients. A then waiting for them. But the problem is that with poll(), my server can listen only one port. But if I delete this function, server accept messages from all ports. What can be a problem?Here's my code:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/poll.h>
int set_non_block_mode(int s)
{
int fl = fcntl(s, F_GETFL, 0);
return fcntl(s, F_SETFL, fl | O_NONBLOCK);
}
void s_close(int s)
{
close(s);
}
int sock_err(const char *function, int s)
{
int err = errno;
fprintf(stderr, "%s: socket error: %d\n", function, err);
return -1;
}
struct client
{
char id[30];
int msgs[20];
struct cl *next;
char send[81];
int amount;
int answer;
};
struct client *addnew(struct client *head)
{
struct client *tmp = (struct client *)calloc(1, sizeof(struct client));
memset(tmp->msgs, 0, 20);
memset(tmp->send, '\0', 81);
memset(tmp->id, '\0', 30);
tmp->amount = 0;
tmp->answer = 0;
tmp->next = NULL;
return tmp;
}
struct client *search(struct client *head, unsigned int ip, int port)
{
char str[30];
sprintf(str, "%u.%u.%u.%u:%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, (ip)&0xFF, port);
struct client *tmp = head;
if (tmp!=NULL){
while (1)
{
if (strcmp(tmp->id, str) == 0)
{
return tmp;
}
if(tmp->next==NULL)break;
tmp = tmp->next;
}
tmp->next = addnew(head);
tmp = tmp->next;
strcpy(tmp->id, str);
return tmp;
} else {
tmp = addnew(head);
strcpy(tmp->id, str);
return tmp;
}
}
int parcing(FILE *text, char *buffer, int s, struct sockaddr_in *addr, struct client *head, int port)
{
int flags = MSG_NOSIGNAL;
int addrlen = sizeof(*addr);
unsigned int ip = ntohl((*addr).sin_addr.s_addr);
struct client *tmp = search(head, ip, port);
int n;
memcpy(&n, buffer, 4);
n = ntohl(n);
if (tmp->msgs[n] == 0)
{
tmp->msgs[n] = 1;
tmp->answer++;
n = htonl(n);
memcpy(&tmp->send[4 * tmp->amount], tmp->send, 4 * tmp->amount);
tmp->amount++;
memcpy(tmp->send, &n, 4);
fprintf(text, "%s %d:%d:", tmp->id, buffer[4], buffer[5]);
memcpy(&n, &buffer[6], 2);
n = ntohs(n);
fprintf(text, "%hu ", n);
memcpy(&n, &buffer[8], 2);
n = ntohs(n);
fprintf(text, "%hi ", n);
for (int i = 10; i < 22; i++)
fprintf(text, "%c", buffer[i]);
fprintf(text, " %s\n", &buffer[22]);
sendto(s, tmp->send, 4 * tmp->amount, flags, (struct sockaddr *)addr, addrlen);
if (strcmp(&buffer[22], "stop") == 0)
return 0;
return 1;
}
else
{
sendto(s, tmp->send, 4 * tmp->amount, flags, (struct sockaddr *)addr, addrlen);
}
}
int main(int argc, char *argv[])
{
int i;
int flags = MSG_NOSIGNAL;
int start, end;
if (argc == 3)
{
start = atoi(argv[1]);
end = atoi(argv[2]);
}
else
{
start = atoi(argv[1]);
end = start;
}
//start = 8035;
//end = start;
int AmountOfPorts = end - start + 1;
struct pollfd *pfd = (struct pollfd *)calloc(AmountOfPorts, sizeof(struct pollfd));
int *s = (int *)calloc(AmountOfPorts, sizeof(int));
struct sockaddr_in *addr = (struct sockaddr_in *)calloc(AmountOfPorts, sizeof(struct sockaddr_in));
for (int i = 0; i < AmountOfPorts; i++)
{
s[i] = socket(AF_INET, SOCK_DGRAM, 0);
if (s[i] < 0)
return sock_err("socket", s[i]);
set_non_block_mode(s[i]);
memset(&addr[i], 0, sizeof(addr));
addr[i].sin_family = AF_INET;
addr[i].sin_port = htons(start + i);
addr[i].sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s[i], (struct sockaddr *)&addr[i], sizeof(addr[i])) < 0)
return sock_err("bind", s[i]);
pfd[i].fd = s[i];
pfd[i].events = POLLIN | POLLOUT;
}
int g = 1;
struct client *head = NULL;
struct client *tmp = NULL;
FILE *text = fopen("msg1.txt", "w");
char buffer[131072] = {0};
int addrlen = 0;
do
{
int ev_cnt = poll(pfd, sizeof(pfd) / sizeof(pfd[0]), 100000);
if (ev_cnt > 0)
{
for (i = 0; i < AmountOfPorts; i++)
{
if (pfd[i].revents & POLLHUP)
{
s_close(s[i]);
}
if (pfd[i].revents & POLLERR)
{
s_close(s[i]);
}
if (pfd[i].revents & POLLIN)
{
addrlen = sizeof(addr[i]);
recvfrom(s[i], buffer, sizeof(buffer), 0, (struct sockaddr *)(&addr[i]), &addrlen);
if (rcv > 0)
{
if (!parcing(text, buffer, s[i], &addr[i], head, start + i))
{
g = 0;
break;
}
}
if (pfd[i].revents & POLLOUT)
{
addrlen = sizeof(addr[i]);
unsigned int ip = ntohl((*addr).sin_addr.s_addr);
tmp = search(head, ip, start+i);
sendto(s[i], tmp->send, 4 * tmp->amount, flags, (struct sockaddr *)&addr[i], addrlen);
}
}
}
}
else
{
}
} while (g);
fclose(text);
for (int i = 0; i < AmountOfPorts; i++)
s_close(s[i]);
return 0;
}
You declare pfd as a pointer to a struct pollfd:
struct pollfd *pfd;
Therefore the following construct will not work as intended (for that to work, pfd would have to be an array: struct pollfd pfd[N]):
sizeof(pfd) / sizeof(pfd[0]) //in call to poll
The above expression could be numerically expressed like this (dependend on your machine and os):
//sizeof(struct pollfd*) / sizeof(struct pollfd)
8 / (4 + 2 + 2) => 8 / 8 => 1
//your expectation:
16 / 8 => 2
That means, poll will listen only to the first pollfd, since the parameter nfds is set to 1.
Note: I didn't fully checked your code, but since you're using pointers (calloc) and sizeof a lot, make sure that you did not made the same mistake at other places. Remember pointer != array.
I am trying to send contents from a big text file from a client to a server line by line, but it always caps out at line 84, even though there are 10000 total lines read from files. It works fine with a smaller file, so I believe the problem lies somewhere in the server receiving buffer, because all the lines are read in the client just fine.
I am a total newbie to C and TCP socket programming, so any insight would be greatly appreciated.
My code so far:
Client
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctype.h>
#define PORT "20000"
#define HOST "::1"
int main()
{
struct addrinfo hints, *res, *result;
int sockfd;
char *line = NULL;
size_t len = 0;
ssize_t readLine;
int number;
FILE *filePointer;
int valread;
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_PASSIVE;
int errcode = getaddrinfo (HOST, PORT, &hints, &result);
if (errcode != 0){
perror ("Nepavyko gauti adreso");
return -1;
}
res = result;
while (res){
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!(sockfd < 0))
break;
res = res->ai_next;
}
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
perror("Prisijungimas nepavyko");
exit(EXIT_FAILURE);
}
filePointer = fopen("dataBIG.txt", "r");
if (filePointer == NULL) {
printf("Nepavyko atidaryti data.txt") ;
}
else {
readLine = getline(&line, &len, filePointer)-1;
sscanf(line, "%d", &number);
send(sockfd, line, sizeof(line), 0);
valread = recv(sockfd, line, sizeof(line), 0);
for(int i = 0; i < number; i++){
readLine = getline(&line, &len, filePointer)-1;
printf("%d\n", i);
if(readLine != 0){
send(sockfd, line, sizeof(line), 0);
}
valread = recv(sockfd, line, sizeof(line), 0);
}
fclose(filePointer);
}
freeaddrinfo(result);
return 0;
}
Server
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctype.h>
#define PORT1 "20000"
#define HOST "::1"
int main()
{
struct addrinfo hints, *res, *result;
int errcode;
char str[300];
void *ptr;
int sockfd, new_socket, valread;
int number;
char *message = "ALL GOOD";
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_PASSIVE;
errcode = getaddrinfo (HOST, PORT1, &hints, &result);
if (errcode != 0){
perror ("Nepavyko gauti adreso");
return -1;
}
res = result;
while (res){
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!(sockfd < 0))
break;
res = res->ai_next;
}
if (bind(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
perror("Bindas neivyko");
exit(EXIT_FAILURE);
}
if (listen(sockfd, 3) < 0){
perror("Listen klaida");
exit(EXIT_FAILURE);
}
int addrlen = sizeof(res);
if ((new_socket = accept(sockfd, (struct sockaddr*)&res, (socklen_t*)&addrlen)) < 0) {
perror("Accept klaida");
exit(EXIT_FAILURE);
}
valread = recv(new_socket, str, sizeof(str), 0);
sscanf(str, "%d", &number);
send(new_socket, message, sizeof(message), 0);
for(int i = 0; i < number; i++){
valread1 = recv(new_socket, str, sizeof(str), 0);
int l = strlen(str);
int j = 0, count = 0;
for(j; j < l; j++){
if ('a' == str[j] || 'A' == str[j])
count++;
}
printf("%d letter A count = %d\n", i+1, count);
sprintf(str, "%d", count);
send(new_socket, message, sizeof(message), 0);
}
freeaddrinfo(result);
return 0;
}
Data file
10000
Hi
Car
Alex
...
if it's a file you should first use:
FILE *File = fopen("Data.txt", "rb");
fseek(File, 0, SEEK_END);
i = ftell(File);
fseek(File, 0, SEEK_SET);
u_int8_t *Memory4Data = (u_int8_t*) malloc (i);
fread(Memory4Data, i, 1, File);
then you shouldn't send them all of them at once:
// allocate 4 byte memory for Memory2Send
Remained_Data = i;
j = 0
while (Remained_Data > 0){
if(Remained_Data > 4){
memcpy(Memory2Send, Memory4Data + j, 4;
send(Sock, Memory2Send, 4, 0);
j = j + 4;
Remained_Data = Remained_Data - 4;
}
else if(Remained_Data < 4){
memcpy(Memory2Send, Memory4Data + j, 4;
send(Sock, Memory2Send, Remained_Data, 0);
Remained_Data = 0;
}
try to send 4 bytes every round.
you'll get all the data
and for server-side you need to receive 4 bytes every round.
j = 1;
z = 0;
while (j != 0) {
bzero(Memory4Recv,4);
recv(Sock, Memory4Recv, 4, 0);
for (i = 0; i < 4; i++){
Recv_Data[z] = Memory4Recv[i];
if (Recv_Data[z] == 0x00){
j = 0;
break;
}
z++;
}
}
put a null byte at the end of the file;
you can do it by :
fread(Memory4Data, i + 1, 1, File);
try to make your file size a multiply of 4 so won't receive any error on receiving the data
if you want to manage your communication better, you can start with creating your own protocol
I tried to check the ports of a host from 0 to 1024 which are open or not. I used getaddrinfo(const char*node, const char *service, const struct addrinfo *hints, struct addrinfo **res) for looping the port numbers from 0 to 1024 (i.e the second parameter const char *service) by converting the int to string and then passing to getaddrinfo(). Is there any way to avoid using this conversion function?
char *convert_int_to_string(int num)
{
int tmp;
int i = 0;
int j = 0;
static char a[5] = {'0'};
while (num > 0) {
tmp = num % 10;
a[i++] = tmp + '0';
num = num / 10;
}
a[i] = '\0';
for (j = 0; j < i / 2; j++) {
tmp = a[j];
a[j] = a[i - j - 1];
a[i - j - 1] = tmp;
}
return a;
}
int main(int argc, char **argv)
{
int status;
char *node;
char *port_no;
int sock_fd;
int i = 0;
struct addrinfo hints, *serviceinfo;
if (argc != 2)
error(1, errno, "Too many or few arguments\n");
node = argv[1];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
for (i = 0; i < 1024; i++) {
port_no = convert_int_to_string(i);
status = getaddrinfo(node, port_no, &hints, &serviceinfo);
if (status != 0) {
error(1, errno, "error in getaddrinfo() function call\n");
}
sock_fd = socket(serviceinfo->ai_family, serviceinfo->ai_socktype, serviceinfo->ai_protocol);
if (sock_fd == -1)
error(1, errno, "error in socket() function call\n");
status = connect(sock_fd, serviceinfo->ai_addr, serviceinfo->ai_addrlen);
if (status != -1)
printf("Port : %s is open\n", port_no);
else
printf("Port : %s is closed\n", port_no);
}
}
Is there any way to omit the usage of int_to_string conversion function in this portscanner code (?)
Yes use snprintf() to form port_no.
for (i = 0; i < 1024; i++) {
// port_no = convert_int_to_string(i);
char port_no[40];
snprintf(port_no, sizeof port_no, "%d", i);
...
I know this is kinda lame question, but what am I doing wrong in my code ? Basically, I wanna create communication on local IP using UDP, also send some files etc. The problem is, that when I get to freeing my structures after using them/converting them to/from char* the program just crashes. What is even more weird, the program does not crash when debugging and stepping through using CLion debugger. What am I doing wrong? Here is my source code:
The error seems to happen, when I can not allocate more memory (so logically, I need to free some) when sending a file over network. Sending messages works just fine
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
// PKS2Visual.cpp : Defines the entry point for the console application.
//
#include "main.h"
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <time.h>
#define BREAKSOMETHING 0
#pragma comment(lib, "ws2_32.lib")
int fragSize = 1500;
int isInside = 0;
SOCKET s1, s2;
struct sockaddr_in server, myClient, otherClient;
int main() {
char mode;
printf("Enter fragment size:\n");
scanf("%d", &fragSize);
p2pMode();
}
DWORD WINAPI receiveThreadFunc(LPVOID lpParam) {
int slen = sizeof(otherClient);
int doRun = 1;
int sizee;
char msgBuffer[1519];
char fileName[1519];
int receivingFile = 0;
while (doRun) {
printf("Waiting for data...\n\n");
if ((recvfrom(s1, msgBuffer, 1519, 0, (struct sockaddr *) &otherClient,
&slen)) == SOCKET_ERROR) {
printf("recvfrom() failed with error code : %d\n", WSAGetLastError());
continue;
}
//printf("Received packet from %s:%d\n", inet_ntoa(otherClient.sin_addr), ntohs(otherClient.sin_port));
PacketData *packetData = dataToPacket(msgBuffer);
if (packetData == NULL) {
continue;
}
char flag = packetData->flag;
switch (flag) {
case 's': {
PacketData *packetDataAck = createPacket('a');
char *messageToSend2 = packetToData(packetDataAck, &sizee);
if (sendto(s1, messageToSend2, 18, 0, (struct sockaddr *) &otherClient, slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
//free(packetDataAck);
//free(messageToSend2);
break;
}
case 'm': {
if (receivingFile) {
FILE *fptr;
fptr = fopen(fileName, "a");
fprintf(fptr, "%s", packetData->data);
printf("Packet contains data: %s\n", packetData->data);
fclose(fptr);
if(packetData->fragNum == packetData->fragTotal){
receivingFile = 0;
}
} else {
printf("Received packet n. %d\n", packetData->fragNum);
printf("Packet data length: %d\n", packetData->len);
printf("Packet contains data: %s\n", packetData->data);
}
break;
}
case 'f': {
strcpy(fileName, packetData->data);
printf("Receiving file: %s\n", fileName);
printf("Receiving file: %s\n", packetData->data);
receivingFile = 1;
break;
}
default: {
doRun = 0;
break;
}
}
free(packetData);
}
return 0;
}
DWORD WINAPI sendThreadFunc(LPVOID lpParam) {
PacketData **fragments = NULL;
int doRun = 1;
char msgBuffer[1500];
int actualSize = 0;
int slen = sizeof(myClient);
while (1) {
printf("Enter message or -e to end messaging and return to menu:\n");
fflush(stdin);
scanf("%1500[^\n]", msgBuffer);
getc(stdin);
if (strcmp(msgBuffer, "-e") == 0) {
isInside = 0;
return 0;
}
if (strlen(msgBuffer) >= 1499) {
continue;
}
fragments = makeFragments(msgBuffer);
int numFragments = fragments[0]->fragTotal;
printf("Number of fragments: %d\n", numFragments);
PacketData *packetData = createPacket('s');
if (packetData == NULL) {
printf("Could not init packet 's'\n");
continue;
}
char *sync = packetToData(packetData, &actualSize);
if (sendto(s2, sync, 18, 0, (struct sockaddr *) &myClient,
slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
printf("First fragment sent.\n");
free(packetData);
char *ack = (char *) calloc(18, sizeof(char));
if (recvfrom(s2, ack, 18, 0, (struct sockaddr *) &myClient, &slen) ==
SOCKET_ERROR) {
printf("recvfrom() failed with error code : %d\n", WSAGetLastError());
continue;
}
free(ack);
printf("Server confirmed first packet.\n");
for (int i = 0; i < fragments[0]->fragTotal; i++) {
char *msgBuffer2 = packetToData(fragments[i], &actualSize);
if (sendto(s2, msgBuffer2, actualSize + 1, 0, (struct sockaddr *) &myClient,
slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
}
free(fragments);
}
return 0;
}
DWORD WINAPI sendFileFunc(LPVOID lpParam) {
char msgBuffer[1500];
int actualSize = 0;
int slen = sizeof(myClient);
while (1) {
printf("Enter file name or -e to return to menu:\n");
fflush(stdin);
scanf("%1500[^\n]", msgBuffer);
getc(stdin);
if (strcmp(msgBuffer, "-e") == 0) {
isInside = 0;
return 0;
}
if (strlen(msgBuffer) >= 1499) {
continue;
}
//Get file length:
FILE *fl = fopen(msgBuffer, "r");
if (fl == NULL) {
printf("Invalid name, try again\n");
continue;
}
fseek(fl, 0, SEEK_END);
long fileLength = ftell(fl);
fclose(fl);
int numFragments = (fileLength - 1) / fragSize + 2;
printf("Number of fragments: %d\n", numFragments);
PacketData *packetData = createPacket('s');
if (packetData == NULL) {
printf("Could not init packet 's'\n");
continue;
}
char *sync = packetToData(packetData, &actualSize);
if (sendto(s2, sync, 18, 0, (struct sockaddr *) &myClient,
slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
printf("First fragment sent.\n");
free(packetData);
char *ack = (char *) calloc(18, sizeof(char));
if (recvfrom(s2, ack, 18, 0, (struct sockaddr *) &myClient, &slen) ==
SOCKET_ERROR) {
printf("recvfrom() failed with error code : %d\n", WSAGetLastError());
continue;
}
//free(ack);
PacketData *fragments = NULL;
fragments = (PacketData *) malloc(sizeof(PacketData));
fragments->data = (char *) malloc(fragSize * sizeof(char));
strncpy(fragments->data, msgBuffer, strlen(msgBuffer));
fragments->data[strlen(msgBuffer)] = '\0';
fragments->flag = 'f';
fragments->len = strlen(msgBuffer);
fragments->fragNum = (unsigned int) (1);
fragments->fragTotal = (unsigned int) numFragments - 1;
fragments->CRC = (unsigned int) calculate_crc(msgBuffer, strlen(msgBuffer));
//Sending the first fragment with 'f' flag
char *toSend = packetToData(fragments, &actualSize);
if (sendto(s2, toSend, actualSize + 1, 0, (struct sockaddr *) &myClient,
slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
printf("Server confirmed first packet.\n");
size_t n = 0;
int counter = 0;
int fragNum = 2;
int c;
FILE *f2 = fopen(msgBuffer, "r");
if(f2 == NULL){
printf("File was null\n");
continue;
}
while ((c = fgetc(f2)) != EOF) {
msgBuffer[n++] = (char) c;
counter++;
if (counter == fragSize) {
n = 0;
counter = 0;
printf("Allocating fragment number: %d\n", fragNum);
PacketData *fragments2 = NULL;
fragments2 = (PacketData *) malloc(sizeof(PacketData));
if(fragments2 == NULL){
printf("Incorrect malloc\n");
break;
}
fragments2->data = (char *) malloc((fragSize+1) * sizeof(char));
if(fragments2->data == NULL){
printf("Incorrect malloc2\n");
break;
}
strncpy(fragments2->data, msgBuffer, fragSize);
printf("Copying data to fragment number: %d\n", fragNum);
fragments2->data[strlen(msgBuffer)] = '\0';
fragments2->flag = 'm';
fragments2->len = (unsigned int) fragSize;
fragments2->fragNum = (unsigned int) (fragNum);
fragments2->fragTotal = (unsigned int) numFragments - 1;
fragments2->CRC = (unsigned int) calculate_crc(msgBuffer, fragSize);
printf("Allocated fragment number: %d\n", fragNum);
fragNum++;
char *toSend = packetToData(fragments2, &actualSize);
if (sendto(s2, toSend, actualSize + 1, 0, (struct sockaddr *) &myClient,
slen) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d\n", WSAGetLastError());
continue;
}
printf("Sent fragment number: %d\n", fragNum);
}
}
fclose(fl);
}
return 0;
}
void p2pMode() {
int serverPort, clientPort;
char *serverAddr = (char *) malloc(20 * sizeof(char));
WSADATA wsa;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
getchar();
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
char hostname[128] = "";
char menuBuffer;
gethostname(hostname, sizeof(hostname));
struct hostent *ent = gethostbyname(hostname);
struct in_addr ip_addr = *(struct in_addr *) (ent->h_addr);
printf("Your IP Address: %s\n", inet_ntoa(ip_addr));
printf("Enter other PC IP Address:\n");
scanf("%s", serverAddr);
if (!strcmp(serverAddr, "localhost"))
serverAddr = (char *) "127.0.0.1";
printf("Enter your listening port:\n");
scanf("%d", &clientPort);
printf("Enter other PC's port:\n");
scanf("%d", &serverPort);
if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
}
if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(inet_ntoa(ip_addr));
server.sin_port = htons(clientPort);
myClient.sin_family = AF_INET;
myClient.sin_port = htons(serverPort);
myClient.sin_addr.S_un.S_addr = inet_addr(serverAddr);
if (bind(s1, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
free(serverAddr);
DWORD dwThreadId, dwThreadId2, dwThreadId3, dwThrdParam = 1;
CreateThread(
NULL, // default security attributes
10000, // use default stack size
receiveThreadFunc, // thread function
&dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
while (1) {
if (!isInside) {
printf("For messages, write 'm', for file 'f'\n");
scanf("%c", &menuBuffer);
switch (menuBuffer) {
case 'm':
CreateThread(
NULL, // default security attributes
10000, // use default stack size
sendThreadFunc, // thread function
&dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId2); // returns the thread identifier
isInside = 1;
break;
case 'f':
CreateThread(
NULL, // default security attributes
10000, // use default stack size
sendFileFunc, // thread function
&dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId3); // returns the thread identifier
isInside = 1;
break;
}
}
}
}
char *packetToData(PacketData *packet, int *size) { // convert packet into sendable data
int sizee = packet->len + 18;
*size = sizee;
char *temp = (char *) calloc(sizee, sizeof(char));
char *out;
if (temp == NULL) {
return NULL;
}
out = temp;
*(temp) = packet->flag;
*(unsigned int *) (temp + 2) = packet->CRC;
*(unsigned int *) (temp + 6) = packet->fragNum;
*(unsigned int *) (temp + 10) = packet->fragTotal;
*(unsigned int *) (temp + 14) = packet->len;
temp = (temp + 18);
int i;
for (i = 0; i < packet->len; i++) { // copy data
temp[i] = packet->data[i];
}
temp[i] = '\0';
return out;
}
PacketData *dataToPacket(char *data) { // convert received data into packet
printf("Data received: %s\n", data);
PacketData *packet = (PacketData *) malloc(sizeof(PacketData));
if (packet == NULL)
return NULL;
packet->flag = *(data);
packet->CRC = *(unsigned int *) (data + 2);
packet->fragNum = *(unsigned int *) (data + 6);
packet->fragTotal = *(unsigned int *) (data + 10);
packet->len = *(unsigned int *) (data + 14);
packet->data = (char *) malloc(packet->len);
char *packetdata = (data + 18);
int i;
for (i = 0; i < packet->len; i++) { // copy data
packet->data[i] = packetdata[i];
}
packet->data[i] = '\0';
return packet;
}
PacketData *createPacket(char flag) {
PacketData *packetData = (PacketData *) malloc(sizeof(PacketData));
packetData->flag = flag;
packetData->len = 0;
packetData->CRC = 0;
packetData->fragNum = 1;
packetData->fragTotal = 1;
return packetData;
}
int calculate_crc(char *buf, int size) {
int crcHash = 10;
for (int i = 0; i < size; i++) {
crcHash += buf[i];
crcHash *= 31;
crcHash %= 30000;
}
return crcHash;
}
struct packetData **makeFragments(char *message) {
int i;
printf("Message length: %d\n", strlen(message));
int fragCount = (strlen(message) - 1) / fragSize + 1;
if (fragCount == 0) {
fragCount++;
}
PacketData **fragments = (PacketData **) malloc((fragCount) * sizeof(PacketData *));
printf("Allocated %d fragments\n", fragCount);
for (i = 0; i < fragCount; i++) {
fragments[i] = (PacketData *) malloc(sizeof(PacketData));
fragments[i]->data = (char *) malloc(fragSize * sizeof(char));
int toCopy = 0;
if (strlen(message) > fragSize) {
toCopy = fragSize;
} else {
toCopy = strlen(message);
}
strncpy(fragments[i]->data, message, toCopy);
fragments[i]->data[toCopy] = '\0';
fragments[i]->flag = 'm';
fragments[i]->len = (unsigned int) toCopy;
fragments[i]->fragNum = (unsigned int) (i + 1);
fragments[i]->fragTotal = (unsigned int) fragCount;
fragments[i]->CRC = (unsigned int) calculate_crc(message, toCopy);
message += fragSize;
}
printf("Fragments needed: %d\n", fragments[0]->fragTotal);
return fragments;
}
and here is my header if someone needed to run it:
//
// Created by lukas on 11/19/2018.
//
#include <winsock2.h>
#include <windows.h>
#ifndef PKS2C_MAIN_H
#define PKS2C_MAIN_H
#endif //PKS2C_MAIN_H
typedef struct packetData {
char flag;
unsigned int CRC;
unsigned int fragNum;
unsigned int fragTotal;
unsigned int len;
char *data;
} PacketData;
struct packetData **makeFragments(char *message);
struct packetData **makeFileFragments(char *message);
char *packetToData(PacketData *packet, int *size);
PacketData *dataToPacket(char *data);
PacketData *createPacket(char flag);
void p2pMode();
int calculate_crc(char *buf, int size);
DWORD WINAPI receiveThread(LPVOID lpParam);
DWORD WINAPI sendThread(LPVOID lpParam);
SOCKET s1, s2;
struct sockaddr_in server, myClient, otherClient;
I realize this concern is almost always due to a simple mistype, but I can't for the life of me find the cause of this error. I've gone through the brackets multiple times and have checked if I'm missing any, but see nothing wrong. Excusing the disgusting way in which I initialized an array, what is wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <sys/poll.h>
#define BufferLength 100
#define SERVPORT 5011
int main(int argc, char * argv[])
{
int sd, sd2, rc, length = sizeof(int);
int totalcnt = 0, on = 1;
char temp;
char buffer[BufferLength];
char init[10];
struct sockaddr_in serveraddr;
struct sockaddr_in their_addr;
fd_set read_fd;
struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;
int new_sd;
int nfds = 1; int len;
//..........................SOCKET SETUP..............................................||
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Socket error");
exit (-1);
}
if((rc = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) < 0)
{
perror("socket setup error");
close(sd);
exit (-1);
}
memset(&serveraddr, 0x00, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVPORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Using %s, listening at %d\n", inet_ntoa(serveraddr.sin_addr), SERVPORT);
//............................BINDING...............................................||
if((rc = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
{
perror("server binding error");
close(sd);
exit(-1);
}
//............................LISTENING.............................................||
if((rc = listen(sd, 8)) < 0)
{ perror("listen error"); close(sd); exit (-1);}
else
printf("Ready for up to eight connections...\n");
int sin_size = sizeof(struct sockaddr_in);
//............................ACCEPTING..............................................||
if((sd2 = accept(sd, (struct sockaddr *)&their_addr, &sin_size)) < 0)
{ perror("Server-accept() error"); close(sd); exit (-1); }
printf("Got connection from the accursed client: %s\n", inet_ntoa(their_addr.sin_addr));
FD_ZERO(&read_fd);
FD_SET(sd2, &read_fd);
//..................................POLL STUFF.......................................||
int i,n;
int m = 0;
char ** init0 = (char**)malloc(9);
for( m; m<10; m+=1)
init0[m] = (char*)malloc(100);
char * left = (char*)malloc(100);
char * enter = (char*)malloc(100);
char ** Tinit0 = (char**)malloc(9);
for(m = 0; m<10; m+=1)
Tinit0[m] = (char*)malloc(100);
memset(left,0,100);
for(m = 0; m<10; m+=1)
memset(Tinit0[m],0,100);
for(m = 0; m<10; m+=1)
memset(init0[m],0,100);
memset(enter, 0, 100);
strcpy(enter,"Entered:_ ");
strcpy(left,"Left: ");
struct pollfd ufds[9];
ufds[0].fd = sd;
ufds[0].events = POLLIN;
ufds[1].fd = sd2;
ufds[1].events = POLLOUT;
ufds[2].fd = sd2;
ufds[2].events = POLLOUT;
ufds[3].fd = sd2;
ufds[3].events = POLLOUT;
ufds[4].fd = sd2;
ufds[4].events = POLLOUT;
ufds[5].fd = sd2;
ufds[5].events = POLLOUT;
ufds[6].fd = sd2;
ufds[6].events = POLLOUT;
ufds[7].fd = sd2;
ufds[7].events = POLLOUT;
ufds[8].fd = sd2;
ufds[8].events = POLLOUT;
//timeout = (6000);
n = poll(ufds, 9, 40000);
do{
for (i = 0; i < 9; i++)
{
if(ufds[i].revents == 0)
continue;
if (ufds[i].fd == sd)
{
do
{
new_sd = accept(sd2, NULL, NULL);
ufds[nfds].fd = new_sd;
ufds[nfds].events = POLLIN;
nfds++;
} while (new_sd != -1);
}
else
{
do
{
rc = recv(ufds[i].fd, buffer, sizeof(buffer), 0);
len =rc;
if(strcmp(init0[i],"") == 0) // IF INITAL HAS NOT BEEN SET UP
{ // (DURING FIRST CONNECTION FROM CLIENT)
if((rc == 1) && (FD_ISSET(sd2, &read_fd)))
{
printf("initial from client is: %s\n",buffer);
strcpy(init0[i],buffer);
printf("init0 is: %s\n", init0[i]); Tinit0[i] = init0[0];
}
strcat(enter, init0[i]);
printf("string enter is: %s , about to try write enter\n",enter);
for(m = 1; m <9; m+=1)
rc = send(ufds[m].fd, enter, 20, 0);
}
strcat(Tinit0[i],"__");
for(m = 1; m <9; m+=1)
rc = send(ufds[m].fd, Tinit0[i], 100, 0);
if(rc==0)
{
strcat(left, init0[i]);
printf("%s\n",left);
for(m = 1; m <9; m+=1)
rc = send(ufds[m].fd, left, 100, 0);
}
} while(1==1);
} //end of else
} //end of for
} //end of do
}
Your do {} while() loop is simply missing the while keyword.