My socket game have some problems, and i can't understand why - c

The code now works fine, but I have some question to ask to you.
The first one is, why received messages are slow (about 1 second)? (not in local)
The second one is, why do I need Sleep function at line 213?
The third one is, why do I need a a confirmation from recv in receiveMessage void, for receive all messages?
On linux socket all is fine.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
#define MAXSIZE 1024
#define PORT 13333
#define FINISH_GAME "cmdfinishgame"
#define RESET_GAME "cmdresetgame"
#define CLOSE_SOCKET "cmdclosesocket"
#define CLEAR_CONSOLE "cmdclearconsole"
const char trustedLetters[27] = "abcdefghijklmnopqrstuvwxyz";
SOCKET serverSocket;
SOCKET clientSocket;
char buffer[MAXSIZE];
char usedLetters[27] = "";
int choose;
void setupServer();
void setupClient();
void sendMessage(char * message);
void receiveMessage(char * message);
int setupGameForServer();
int setupGameForClient();
void startGame();
void spectGame();
void getAUXofStr(char * _Src, char * _Dest);
void spaceString(char * _Src, char * _Dest);
void getChar(char *c);
void waitForUserInput();
void replace(char * _Str, char _Which, char _With);
main.c:
#include "main.h"
int main()
{
while (1)
{
system("cls");
printf("----------------------- \n");
printf("[1] Crea una stanza \n");
printf("[2] Entra in una stanza \n");
printf("----------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
//Inizializzo lato server
setupServer();
//Aspetto che qualcuno si connetta
SOCKADDR_IN clientInfo;
int clientSize = sizeof(clientInfo);
clientSocket = accept(serverSocket, (LPSOCKADDR)&clientInfo, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
exit(1);
}
closesocket(serverSocket);
//in
while (setupGameForServer() == 0);
break;
}
else if (choose == 2)
{
//Inizializzo lato client
setupClient();
while (setupGameForClient() == 0);
break;
}
else if (choose == 99)
{
break;
}
}
closesocket(clientSocket);
WSACleanup();
return 0;
}
int setupGameForServer()
{
memset(usedLetters, 0, sizeof(usedLetters));
memset(buffer, 0, sizeof(buffer));
//Inizia nuova partita
while (1)
{
system("cls");
printf("---------------------------- \n");
printf("[1] Inizia nuova partita \n");
printf("[2] Chiudi \n");
printf("---------------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
sendMessage(RESET_GAME);
break;
}
else if (choose == 2)
{
sendMessage(CLOSE_SOCKET);
return 1;
}
else
{
printf("Errore! Inserire un opzione valida! \n\n\n");
waitForUserInput();
}
}
//-------------
//Chi indovina?
while (1)
{
system("cls");
printf("---------------------- \n");
printf("[1] Indovina il server \n");
printf("[2] Indovina il client \n");
printf("---------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
sendMessage("1");
startGame();
}
else if (choose == 2)
{
sendMessage("2");
printf("Inserisci la frase: ");
scanf(" %[^\n]", buffer);
printf("\n");
sendMessage(buffer);
spectGame();
}
else
{
printf("Errore! Inserire un opzione valida! \n\n\n");
waitForUserInput();
continue;
}
break;
}
//-------------
return 0;
}
int setupGameForClient()
{
//
receiveMessage(buffer);
if (strcmp(buffer, RESET_GAME) == 0)
{
memset(usedLetters, 0, sizeof(usedLetters));
memset(buffer, 0, sizeof(buffer));
}
else if (strcmp(buffer, CLOSE_SOCKET) == 0)
{
return 1;
}
Sleep(10);
//printf("OK!"); //wtf?
//
receiveMessage(buffer);
int i = atoi(buffer);
if (i == 1)
{
printf("Inserisci la frase: ");
scanf(" %[^\n]", buffer);
printf("\n");
sendMessage(buffer);
spectGame();
}
else if (i == 2)
{
startGame();
}
return 0;
}
void setupServer()
{
//Inizializzazione winsock
WSADATA wsaData;
WORD version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData))
{
exit(1);
}
//Creazione socket
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
exit(1);
}
//Bind dell'ip e della porta
SOCKADDR_IN serverInfo;
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = ADDR_ANY;
serverInfo.sin_port = htons(PORT);
bind(serverSocket, (LPSOCKADDR)&serverInfo, sizeof(serverInfo));
//Messa del socket in ascolto
listen(serverSocket, 1);
}
void setupClient()
{
//Inizializzazione winsock
WSADATA wsaData;
WORD version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData))
{
exit(1);
}
//Creazione socket
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET)
{
exit(1);
}
//ip
char ip[16];
printf("Inserisci ip: ");
scanf("%s", ip);
printf("\n");
//Mi connetto al server
SOCKADDR_IN clientInfo;
clientInfo.sin_family = AF_INET;
clientInfo.sin_addr.s_addr = inet_addr(ip);
clientInfo.sin_port = htons(PORT);
connect(clientSocket, (LPSOCKADDR)&clientInfo, sizeof(clientInfo));
}
void startGame()
{
receiveMessage(buffer);
char *phrase;
char *phraseAUX;
phrase = (char *)malloc(strlen(buffer) * sizeof(char));
phraseAUX = (char *)malloc(strlen(buffer) * sizeof(char));
memcpy(phrase, buffer, strlen(buffer));
phrase[strlen(buffer)] = '\0';
phraseAUX[strlen(buffer)] = '\0';
getAUXofStr(phrase, phraseAUX);
system("cls");
sendMessage(CLEAR_CONSOLE);
char c;
int flag = 0;
int lives = 5;
while (1)
{
//stampo lo status
spaceString(phraseAUX, buffer);
printf(buffer);
printf("\n");
sendMessage(buffer);
sendMessage("\n");
snprintf(buffer, 10, "%d", lives);
printf("Vite rimaste: ");
printf(buffer);
printf("\n");
sendMessage("Vite rimaste: ");
sendMessage(buffer);
sendMessage("\n");
//Vedo se ho vinto
if (strcmp(phrase, phraseAUX) == 0)
{
printf("Hai vinto! \n");
sendMessage("Hai scelto una parola troppo easy colione! \n");
break;
}
//Vedo se ho perso
if (lives <= 0)
{
printf("Hai perso! La parola era: \"%s\"\n", phrase);
sendMessage("Il tuo amico finocchio ha perso! GGEZ! \n");
break;
}
//Inserimento carattere
printf("Inserisci carattere: ");
getChar(&c);
printf("\n");
system("cls");
sendMessage(CLEAR_CONSOLE);
//Vedo se la lettera è valida
flag = 0;
for (int i = 0; i < strlen(usedLetters); i++)
{
if (tolower(c) == usedLetters[i])
{
printf("Lettera già utilizzata! \n");
sendMessage("Il tuo amico non capisce un cazzo, ha riinserito la stessa lettera! \n");
flag = 1;
break;
}
}
if (flag)
continue;
else
strncat(usedLetters, &c, 1);
//Sostituisco la lettera nella stringa ausiliaria
flag = 0;
for (int i = 0; i < strlen(phrase); i++)
{
if (tolower(c) == tolower(phrase[i]))
{
phraseAUX[i] = phrase[i];
flag = 1;
}
}
if (!flag)
lives -= 1;
}
waitForUserInput();
sendMessage(FINISH_GAME);
printf("\n\n");
}
void spectGame()
{
while (1)
{
receiveMessage(buffer);
if (strcmp(buffer, CLEAR_CONSOLE) == 0)
{
system("cls");
}
else if (strcmp(buffer, FINISH_GAME) == 0)
{
break;
}
else
{
printf("%s", buffer);
}
}
}
void receiveMessage(char *message)
{
int result;
memset(message, 0, sizeof(message));
//u_long mode = 1; // 1 to enable non-blocking socket
//ioctlsocket(clientSocket, FIONREAD, &mode);
result = recv(clientSocket, message, MAXSIZE, 0);
if (result == 0)
{
exit(1);
}
send(clientSocket, "1", 2, 0);
}
void sendMessage(char *message)
{
int result;
char localBuffer[2];
//u_long mode = 1; // 1 to enable non-blocking socket
//ioctlsocket(clientSocket, FIONBIO, &mode);
result = send(clientSocket, message, (int)strlen(message) + 1, 0);
if (result == 0)
{
exit(1);
}
recv(clientSocket, localBuffer, 2, 0);
if (strcmp(localBuffer, "1") != 0) {
waitForUserInput();
exit(1);
}
}
void getChar(char *c)
{
char str[MAXSIZE];
scanf("%s", str);
*c = str[0];
}
void getAUXofStr(char *_Src, char *_Dest)
{
char trustedLetters[] = "abcdefghijklmnopqrstuvwxyz";
int flag = 0;
for (int s1 = 0; s1 < strlen(_Src); s1 += 1)
{
flag = 0;
for (int s2 = 0; s2 < strlen(trustedLetters); s2 += 1)
{
if (tolower(_Src[s1]) == trustedLetters[s2])
{
_Dest[s1] = '_';
flag = 1;
break;
}
}
if (!flag)
_Dest[s1] = _Src[s1];
}
}
void spaceString(char *_Src, char *_Dest)
{
char finalstr[MAXSIZE];
char space = ' ';
ZeroMemory(finalstr, sizeof(finalstr));
for (int s1 = 0; s1 < strlen(_Src); s1 += 1)
{
strncat(finalstr, &_Src[s1], 1);
strncat(finalstr, &space, 1);
}
strcpy(_Dest, finalstr);
}
void waitForUserInput()
{
printf("Premere un tasto per continuare...\n");
fflush(stdin);
getchar();
}

Related

Why second input from client side is marked as wrong input?

I have created a client server application in C (TCP) and my codes are all working find (functions). However, from the client side, when I enter a command, for example "time", the server returns the correct response, but on second time executing the same command, the server returns "invalid command"
This is my server.c, creating of the different threads and all are working perfectly.
void menu(int connfd, int i)
{
while(TRUE)
{
userMenu();
write(connfd, buffer, sizeof(buffer));
//read command
bzero(buffer, MAX);
read(connfd, buffer, MAX);
if (CheckValidCommand(buffer) != TRUE)
{
bzero(buffer, MAX);
strcpy(buffer, "Invalid Command\n");
write(connfd, buffer, sizeof(buffer));
}
else
{
char* token = strtok(buffer, " ");
char command[20];
strcpy(command, ConvertToLower(token));
if (strcmp(command, "join") == 0)
{
Join(connfd, buffer);
}
else if (strcmp(command, "whois") == 0)
{
//Get username
token = strtok(NULL, " ");
bzero(buffer, MAX);
strcpy(buffer, WhoIs(connfd, token));
write(connfd, buffer, sizeof(buffer));
}
else if (strcmp(command, "msg") == 0)
{
//Get username
token = strtok(NULL, " ");
Chat(connfd, token, buffer);
}
else if (strcmp(command, "time") == 0)
{
bzero(buffer, MAX);
strcpy(buffer, GetTime());
write(connfd, buffer, sizeof(buffer));
}
else if (strcmp(command, "alive") == 0)
{
Alive(connfd);
}
else if (strcmp(command, "quit") == 0)
{
Quit(connfd);
}
}
}
CheckConnectedUser();
}
And this is my client.c
int CheckValidCommand(char buff[])
{
int isValid = FALSE;
int wordCount = 0;
char tokens[5][20];
for (int i = 0; i < strlen(buff) - 1; i++)
{
if (buff[i] == ' ')
{
wordCount++;
}
}
wordCount++;
char* token = strtok(buff, " ");
token = ConvertToLower(token);
if (strcmp(token, "join") == 0)
{
int pos = 0;
int totalTokens = 0;
while (token != NULL)
{
if (strlen(token) > 20)
return FALSE;
strcpy(tokens[totalTokens], token);
totalTokens++;
token = strtok(NULL, " ");
}
totalTokens--;
char* Name = malloc(sizeof(char) * 20);
char* Username = malloc(sizeof(char) * 20);
//Get UserName
strcpy(Username, tokens[1]);
strcpy(Name, tokens[2]);
strcat(Name, " ");
//Get name
for (int x = 2; x < totalTokens - 1; x++)
{
strcat(Name, " ");
strcat(Name, tokens[x]);
}
strcat(Name, tokens[totalTokens]);
if (strlen(Name) > 20 || strlen(Username) > 20)
return FALSE;
else
return TRUE;
}
else if (strcmp(token, "whois") == 0)
{
if (wordCount > 2)
return FALSE;
token = strtok(NULL, " ");
if (strlen(token) > 20)
return FALSE;
return TRUE;
}
else if (strcmp(token, "msg") == 0)
{
token = strtok(NULL, " ");
if (strlen(token) > 20)
return FALSE;
char txt[MAX];
while (token != NULL)
{
strcat(txt, token);
strcat(txt, " ");
}
strcpy(txt, RemoveExtraSpace(txt));
if (strlen(txt) > 256)
return FALSE;
return TRUE;
}
else if (strcmp(token, "time") == 0)
{
if (strtok(NULL, " ") == NULL)
return TRUE;
else
return FALSE;
}
else if (strcmp(token, "alive") == 0)
{
if (strtok(NULL, " ") == NULL)
return TRUE;
else
return FALSE;
}
else if (strcmp(token, "quit") == 0)
{
if (strtok(NULL, " ") == NULL)
return TRUE;
else
return FALSE;
}
else
{
return FALSE;
}
}
int main(int argc,char* argv[])
{
if (argc != 3)
{
printf("Run with : \n");
printf("\t./client ip_address port_number\n");
printf("\t\tWhere ipaddress is ipv4 address\n");
printf("\t\tWhere port_number is open port number\n");
}
else
{
int sockfd, connfd, n;
char currChar;
struct sockaddr_in servaddr, cli;
char ipaddress[20];
memcpy(ipaddress, argv[1], strlen(argv[1]));
// socket create and varification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed!\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, ipaddress, &(servaddr.sin_addr));
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0)
{
printf("connection with the server failed!\n");
exit(0);
}
while (TRUE)
{
//read menu
bzero(buffer, MAX);
read(sockfd, buffer, sizeof(buffer));
printf("%s", buffer);
bzero(buffer, MAX);
n = 0;
while ((buffer[n++] = getchar()) != '\n');
buffer[strcspn(buffer, "\n")] = 0;
write(sockfd, buffer, sizeof(buffer));
//read response
bzero(buffer, MAX);
read(sockfd, buffer, sizeof(buffer));
printf("%s\n", buffer);
}
// close the socket
close(sockfd);
}
return 0;
}

C Socket program doesn't print desired output (No Error)

I can't seem to print what I enter in my client. I have compiled both without any error. Can't figure out why it isn't printing the desired output.
Q. What is wrong with my code ? How can I print a string with whitespaces through the client in the server.
Here is the code for the server.
/* Server Side program */
int sid,nid;
struct sockaddr_in q;
char x[100];
int len=sizeof(struct sockaddr_in);
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
bind(sid,&q,len);
listen(sid,20);
while(1)
{
memset(x,0,sizeof(x));
nid=accept(sid,&q,&len);
read(nid,x,100);
printf("%s\n",x);
}
Here is the code for the client.
/*client side program*/
int sid,status;
struct sockaddr_in q;
int len=sizeof(struct sockaddr_in);
char x[100];
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
status=connect(sid,&q,len);
if(status==-1)
{
printf("Connection failure");
exit(0);
}
while(1)
{
printf("Enter string to send : ");
scanf("%[^\n]s",x);
write(sid,x,strlen(x));
if(strcmp(x,"bye")==0)
break;
}
There is all kinds of problems with your code. Lack of error handling. Incorrect use of printf() and scanf(). Resource leaks.
Try something more like this instead:
Server:
int main()
{
int sid, nid;
struct sockaddr_in q;
char x[100];
socklen_t qlen;
ssize_t xlen;
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = INADDR_ANY;
if (bind(sid, &q, sizeof(q)) < 0)
{
perror("bind failure");
return -1;
}
if (listen(sid, 20) < 0)
{
perror("listen failure");
return -1;
}
while(1)
{
qlen = sizeof(q);
nid = accept(sid, &q, &qlen);
if (nid < 0)
{
perror("accept failure");
return -1;
}
while ((xlen = read(nid, x, sizeof(x))) > 0)
{
printf("Received: '%.*s'\n", xlen, x);
}
if (xlen < 0)
perror("read failure");
else
printf("client disconnected\n");
close(nid);
}
return 0;
}
Client:
int main()
{
int sid, xlen;
struct sockaddr_in q;
char x[100];
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = inet_addr("server ip here"); // or INADDR_LOOPBACK (127.0.0.1)
if (connect(sid, &q, sizeof(q)) < 0)
{
printf("connect failure");
return -1;
}
while(1)
{
printf("Enter string to send : ");
if (!fgets(x, sizeof(x), stdin))
break;
xlen = strlen(x);
if ((xlen > 0) && (x[xlen-1] == '\n'))
{
x[xlen-1] = '\0';
--xlen;
}
if (write(sid, x, xlen) < 0)
{
perror("write failure");
break;
}
if (strcmp(x, "bye") == 0)
break;
}
close(sid);
return 0;
}

TCP server not waiting for client response?

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, &currency);
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);
}

Writing my own shell for redirecting and pipes in C

I have been trying to write a shell in C but i keep getting e segmentation fault when running ls > test.txt (before implementing pipes it worked just fine) .
Here is the code. sorry if it is too long and not formated properly.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX 1024
/* fonction separe donne en exercise*/
char **separe(char *chaine, const char *separateurs)
{
char **tab;
int i, s, m, size = 10;
tab = malloc(size * sizeof(char*));
m = 0;
i = 0;
while (chaine[i] != 0)
{
// saute un séparateur
for (s = 0; separateurs[s] != 0; s++)
if (chaine[i] == separateurs[s])
break;
if (separateurs[s] != 0)
{
chaine[i++] = 0; // met un fin de chaine à la place du séparateur et avance
continue; // les séparateurs n'ont pas été épuisés
}
if (chaine[i] != 0)
tab[m++] = chaine + i;
if (m == size)
{
// si j'atteinds la limite de la taille de mon tableau, je l'agrandis.
size += 10;
tab = realloc(tab, size * sizeof(char*));
}
// saute les caractères non séparateurs
for (; chaine[i] != 0; i++)
{
for (s = 0; separateurs[s] != 0; s++)
if (chaine[i] == separateurs[s])
break;
if (separateurs[s] != 0)
break; // trouvé un caractère séparateur, j'arrête d'avancer et je passe au mot suivant
}
}
tab[m] = NULL;
return(tab);
}
void decaler2gauche(char ** tab, int pos)
{
int i = pos;
while( tab[i+2] != NULL )
{
tab[i] = tab[i+2];
i++;
}
tab[i] = NULL;
}
char** pipetest( char **arg) {
int sizeTab = 0;
int k,j;
char **newtab;
for (k = 0; arg[k] != NULL; k++)
{
sizeTab++;
}
int i =0;
while( arg[i] != NULL )
{
if( strncmp(arg[i],"|",1) == 0 )
{
for (j=0;j < i ; j++){
newtab[i] = arg[i];
}
break;
}
i++;
}
newtab[i] = NULL;
return newtab;
}
char** pipetest2( char **arg) {
int sizeTab = 0;
int k , j;
char **newtab;
for (k = 0; arg[k] != NULL; k++)
{
sizeTab++;
}
int i =0;
while( arg[i] != NULL )
{
if( strncmp(arg[i],"|",1) == 0 )
{
for ( j= i+1 ; j < sizeTab ; j++ ) {
newtab[j] = arg[j];
}
break;
}
i++;
}
newtab[sizeTab] = NULL;
return newtab;
}
/* la fonction main*/
int main(int argc, char *argv[]) {
char cmd[MAX];
char **commande; //ici on met la commande
char *newcommande[MAX]; // ici on met la commande apres avoir verifie le contenu de commande
int i, j, k,t,a, fd, fd2, raison ; // les variables utilise
char *tmp, *new_path , *new_path1 , *new_path2;
char *ge_path, *path, **tab;
int test;
int status , status2; // la variable test pour le access
char **commande1;
char **commande2;
pid_t pid , pid2;
// récupère la valeur de $PATH
ge_path = getenv("PATH");
// crée une copie locale modifiable
// (on ne doit pas modifier la zone mémoire renvoyée par getenv)
path = malloc(strlen(ge_path) + 1);
strcpy(path, ge_path);
tab = separe(path, ":");
while (1) {
int copy = 0;
int paste = 0;
int piping = 0;
int fdout;
int fdin;
int tabfd[2];
printf("myshell > ");
fgets(cmd, MAX, stdin);
commande = separe(cmd, " \n");
/* Cette boucle verifie si la commande passe en parametre est dans le PAth ou pas*/
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path = tmp;
break;
}
}
char* fileNameIn;
char* fileNameOut;
for (j = 0; commande[j] != NULL; j++)
{
if (strcmp(commande[j], ">") == 0) //out
{
fileNameOut = commande[j + 1];
fdout = open(fileNameOut, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdout == -1)
{
perror("open\n");
exit(1);
}
decaler2gauche(commande,j);
copy = 1;
}
if (strcmp(commande[j], "<") == 0) //in
{
fileNameIn = commande[j + 1];
printf("%s\n", fileNameIn);
fdin = open(fileNameIn, O_RDONLY);
if (fdin == -1)
{
perror("open\n");
exit(1);
}
paste = 1;
decaler2gauche(commande,j);
}
if (strcmp(commande[j], "|") == 0) // pipe {
{
piping = 1;
}
newcommande[j] = commande[j];
}
if (piping) {
commande1=pipetest(newcommande);
commande2=pipetest2(newcommande);
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande1[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path1 = tmp;
break;
}
}
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande2[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path2 = tmp;
break;
}
}
pipe(tabfd);
switch (pid=fork()) {
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
close(1);
dup(tabfd[1]);
if (paste)
{
if (dup2(fdin, 0) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
if (copy)
{
if (dup2(fdout, 1) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
execv(new_path1, commande1);
perror("cmd");
exit(1);
default :
wait(&status2);
break;
}
switch (pid2=fork()) {
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
close(0);
dup(tabfd[0]);
if (paste)
{
if (dup2(fdin, 0) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
if (copy)
{
if (dup2(fdout, 1) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
execv(new_path2, commande2);
perror("cmd");
exit(1);
default :
wait(&status);
break;
}
close(tabfd[0]);
close(tabfd[1]);
}
else {
switch (pid = fork())
{
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
if (paste)
{
if (dup2(fdin, STDIN_FILENO) == -1)
{
perror("dup2 fdin \n");
exit(1);
};
}
if (copy)
{
if (dup2(fdout, STDOUT_FILENO) == -1)
{
perror("dup2 fdin \n");
exit(1);
};
}
execv(new_path, commande);
perror("cmd");
exit(1);
default:
wait(&status);
break ;
}
}
free(commande);
free(tmp);
}
free(tab);
//free(commande);
free(path);
free(new_path);
exit(0);
}

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.

Resources