Related
This is client code by using libwebsocket version 1.5
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <syslog.h>
#include <sys/time.h>
#include <unistd.h>
#include <libwebsockets.h>
static volatile int force_exit = 0;
static int state, command_received = 0, forked = 0;
#define MAX_ECHO_PAYLOAD 1400
#define LOCAL_RESOURCE_PATH "./"
struct per_session_data {
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING];
unsigned int len;
};
//for temporary storing data from tcpdump
struct per_session_data data1;
static int callback_echo(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len)
{
struct per_session_data *pss = (struct per_session_data *)user;
int n;
switch (reason) {
/* when the callback is used for client operations --> */
case LWS_CALLBACK_CLOSED:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
printf("Closed\n");
state = 0;
break;
case LWS_CALLBACK_ESTABLISHED:
case LWS_CALLBACK_CLIENT_ESTABLISHED:
printf("Client connected\n");
state = 2;
break;
/* we will receive our packet here*/
case LWS_CALLBACK_RECEIVE:
case LWS_CALLBACK_CLIENT_RECEIVE:
printf("Rx from server: %s\n", (char *)in);
if (!strcmp((char *)in, "tcpdump"))
{
command_received = 1;
}
break;
/* we will send our packet here */
case LWS_CALLBACK_CLIENT_WRITEABLE:
printf("client writing to server\n");
pss->len = sprintf((char *)&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);
n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT);
printf("Data: %s\n\n\n\n\n\n\n", &pss->buf[LWS_SEND_BUFFER_PRE_PADDING]);
//error handling for write fail and partial writes
if (n < 0) {
printf("ERROR %d writing to socket, hanging up\n", n);
return -1;
}
if (n < (int)pss->len) {
printf("Partial write\n");
return -1;
}
break;
default:
printf("default...\n");
break;
}
return 0;
}
/* List of available protocols */
static struct libwebsocket_protocols protocols[] = {
{
"default", /* name */
callback_echo, /* callback */
sizeof(struct per_session_data) /* per_session_data_size */
},
{
NULL, NULL, 0 /* End of list */
}
};
void sighandler(int sig)
{
force_exit = 1;
}
int main(int argc, char **argv)
{
//pipe stuff
int pipe_fd[2];
if (pipe(pipe_fd) < 0)
{
perror("PIPE:");
exit(-1);
}
//for libwebsocket_service
int n = 0;
//test port can be overidden
int port = 9000;
struct libwebsocket_context *context;
int opts = 0;
char interface_name[128] = "";
const char *interface = NULL;
int use_ssl = 0;
char ssl_cert[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
char ssl_key[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
int listen_port = 80;
struct lws_context_creation_info info;
char passphrase[256];
char uri[256] = "/";
char address[256], ads_port[256 + 30];
//lws servicing time intervals
int rate_us = 250000;
unsigned int oldus = 0;
struct libwebsocket *wsi;
//should check this
int debug_level = 2;
memset(&info, 0, sizeof info);
lwsl_notice("Built to support client operations\n");
//re-configuring server ip and port here
if (argc == 3)
{
strncpy(address, argv[1], sizeof(address) - 1);
address[sizeof(address) - 1] = '\0';
port = atoi(argv[2]);
}
else if (argc == 1)
{
strncpy(address, "localhost", sizeof(address) - 1);
address[sizeof(address) - 1] = '\0';
port = 9000;
}
else
{
printf("Try: ./client.exec <ip> <port>\n");
exit(-1);
}
/* we will only try to log things according to our debug_level */
setlogmask(LOG_UPTO (LOG_DEBUG));
openlog("lwsts", 0, LOG_DAEMON);
/* tell the library what debug level to emit and to send it to syslog */
lws_set_log_level(debug_level, lwsl_emit_syslog);
lwsl_notice("libwebsockets echo test - "
"(C) Copyright 2010-2015 Andy Green <andy#warmcat.com> - "
"licensed under LGPL2.1\n");
lwsl_notice("Running in client mode\n");
listen_port = CONTEXT_PORT_NO_LISTEN;
lwsl_info("requiring server cert validation againts %s\n", ssl_cert);
info.ssl_ca_filepath = ssl_cert;
info.port = listen_port;
info.iface = interface;
info.protocols = protocols;
#ifndef LWS_NO_EXTENSIONS
info.extensions = libwebsocket_get_internal_extensions();
#endif
info.gid = -1;
info.uid = -1;
info.options = opts;
context = libwebsocket_create_context(&info);
if (context == NULL) {
lwsl_err("libwebsocket init failed\n");
return -1;
}
signal(SIGINT, sighandler);
n = 0;
while (n >= 0 && !force_exit)
{
//do connect only once
if (!state) {
state = 1;
printf("Client connecting to %s:%u....\n", address, port);
address[sizeof(address) - 1] = '\0';
sprintf(ads_port, "%s:%u", address, port & 65535);
wsi = libwebsocket_client_connect(context, address, port, use_ssl, uri, ads_port, ads_port, NULL, -1);
if (!wsi) {
printf("Client failed to connect to %s:%u\n", address, port);
goto bail;
}
}
if (command_received == 1 && !forked)
{
printf("Going to fork\n");
forked = 1;
pid_t child_pid = fork();
if (child_pid == -1)
{
perror("FORK:");
exit(-1);
}
else if (child_pid == 0)
{
close(pipe_fd[0]);
printf("Starting tcpdump\n");
if (dup2(pipe_fd[1], 1) < 0)
{
perror("DUP2:");
exit(-1);
}
//closing the connection to server for child
libwebsocket_context_destroy(context);
closelog();
char *cmd[] = {"tcpdump", "-i", "any", NULL};
if (execv("/usr/sbin/tcpdump", cmd) < 0)
{
perror("EXECV:");
exit(-1);
}
}
}
/* if (forked == 1)
{
close(pipe_fd[1]);
}
*/
if (command_received == 1)
{
//stay here if the pipe is empty else try to read max 1400 bytes of data
while ((data1.len = read(pipe_fd[0], data1.buf + LWS_SEND_BUFFER_PRE_PADDING, 1400)) <= 0);
//check if server wants any service
//printf("%s\n\n\n\n\n\n\n", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);
libwebsocket_callback_on_writable(context, wsi);
}
//This fn times out every 10usec
n = libwebsocket_service(context, 10);
}
//bail: jump from while loop also if connect fails
bail:
libwebsocket_context_destroy(context);
printf("libwebsockets-test-echo exited cleanly\n");
closelog();
return 0;
}
This is my server code by using socket.io
var io = require('socket.io')();
var middleware = require('socketio-wildcard')();
io.use(middleware);
io.on('connection', function(socket) {
console.log('On socket connection')
socket.on('*', function(event, data){
console.log("---- Event ----- : " + JSON.stringify(event));
console.log("---- Data ----- : " + JSON.stringify(data))
});
});
io.listen(9000, 'localhost');
The client is unable to connect with server. when i tested client with strace it infinitely does receive as below
recv(8, "", 1, 0) = 0
recv(8, "", 1, 0) = 0
recv(8, "", 1, 0) = 0
.
.
.
.
Please point out my mistake. Any help is appreciated.
Thanks
I have a broadcast program on my mac, everything is working fine, but if i have more then one network interface, he didn't recieve anything.
So what i now want to do is:
Check which network interfaces are activ on the mac
send to every activ interface a broadcast ( so i have to select which interface i want to use)
recieve the answer (if there is one :) )
Interesting:
the broadcast client is on my WLAN (with a router beetween the devices) and a normal internet connection is on my LAN. If i deactivate the LAN in the system configs, he also didn't find my other device, but if i pull the cable he found the other device... So maybe i didn't have to look which interface is activ and have a look to which interface is connected.
Do u have some tipps or good google keywords for me to do that?
Long time ago, but if someone find my post, here is my solution:
#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while ((shift >= 0) && (*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char)atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
int Broadcast::BroadcastToAllInterfaces()
{
DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
globalDatabase->SetInBroadcast();
moreThenOne = 0;
#if defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while (p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
addr << dstAddrStr;
descss << p->ifa_name;
descss >> descs;
addr >> addrs;
DoABroadcast(dstAddr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it STILL_RUN
ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while ((next) && (name == NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while (ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
int setUnnamed = 0;
if (name == NULL)
{
sprintf(buf, "unnamed");
name = buf;
setUnnamed = 1;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
if (setUnnamed == 0)
{
addr << dstAddrStr;
descss << desc;
descss >> descs;
addr >> addrs;
DoABroadcast(baddr);
}
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
globalDatabase->SetLeaveBroadcast();
return 1;
}
int Broadcast::DoABroadcast(uint32 broadAddr)
{
int askSinlen = sizeof(struct sockaddr_in);
int askBuflen = MAXBUF;
int message;
char buf[512];
int status;
char askBuffer[MAXBUF];
struct sockaddr_in sock_in, client_adress, client_adress2;
#ifdef __APPLE__
socklen_t clientLength;
int askYes = 1;
#else
char askYes = 1;
int clientLength;
WSADATA w;
int result = WSAStartup(MAKEWORD(2, 2), &w);
#endif
int recSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (recSocket <0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(4028);
sock_in.sin_family = PF_INET;
client_adress.sin_family = PF_INET;
client_adress.sin_port = htons(4029);
client_adress.sin_addr.s_addr = htonl(broadAddr);
askSinlen = sizeof(sock_in);
client_adress2.sin_family = AF_INET;
client_adress2.sin_port = htons(4028);
client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);
status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");
status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
fd_set fds;
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(recSocket, &fds);
int ret;
if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
{
int e = 0;
while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
{
clientLength = sizeof(client_adress2);
message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);
if (message == -1)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -5;
}
else
{
std::string hereisyourbroadcast(buf);
}
}
}
else
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -6;
}
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 1;
}
Hey there wonderful community!
I'm back with a question regarding a console server application I've made with winsock. It's finally reaching a stage where I would need a to add a GUI, and to do so, I need it to be using the Windows subsystem.
And so I started the migration.
Yet I'm hitting a stack overflow somewhere in my application, and for the life of me I can't figure out where. Perhaps it has to do with WIN being a non-blocking subsystem (hope I used my vocab correctly).
Anyway, I hope to enlist you all as helpers. Many thanks :)
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <conio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
int minitialize();
int msend(char msendbuf[512]);
char* mrecv(bool show);
int mshutdown();
void GoToXY(int column, int line);
int scroll(void);
int printm(char *inp);
int printm(char *inp, DWORD color);
int mexit();
char *vir = "true";
int clientnumber=0;
int currentclient=0;
int lastclient=0;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "10150"
struct _client
{
bool con;
sockaddr_in addr; //Client info like ip address
SOCKET cs; //Client socket
fd_set set; //used to check if there is data in the socket
std::string ip;
std::string name;
int i; //any piece of additional info
} client[100];
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
DWORD WINAPI recvfunc(LPVOID randparam)
{
while (true) {
ClientSocket=client[currentclient].cs;
if (mrecv(true)=="1") {
client[currentclient].con=false;
ClientSocket=client[lastclient].cs;
break;
}
}
return 0;
}
DWORD WINAPI headerfunc(LPVOID randparam)
{
Sleep(500);
while (true) {
CONSOLE_SCREEN_BUFFER_INFO SBInfo;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hOut, &SBInfo);
int xx = SBInfo.dwCursorPosition.X;
int yy = SBInfo.dwCursorPosition.Y;
GoToXY(0,0);
HANDLE hHeaderColor;
hHeaderColor = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hHeaderColor, FOREGROUND_GREEN);
std::cout<<"Server Started. Current Client:"<<currentclient<<" Clients connected: "<<clientnumber<<" ("<<xx<<","<<yy<<") "<<lastclient;
SetConsoleTextAttribute(hHeaderColor, 0 |
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
GoToXY(xx,yy);
Sleep(2000);
}
return 0;
}
DWORD WINAPI sendfunc(LPVOID randparam)
{
while (true) {
char mmessage[512];
std::cin.getline(mmessage, 512);
if (strlen(mmessage)<2) {
GoToXY(0,23);
sendfunc("1");
}
char msendbuf[512]="Server> ";
strcat(msendbuf,mmessage);
if (msend(msendbuf)==1) {
"Client must have disconnected. Please select a new client.";
sendfunc("1");
}
if ((strncmp(msendbuf,"Server> /",9)) != 0) {
printm(msendbuf,FOREGROUND_INTENSITY);
}
GoToXY(0,23);
for (int sp=0; sp<72; sp++) {
std::cout<<" ";
}
GoToXY(0,23);
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
minitialize();
HANDLE hRecvThread;
HANDLE hSendThread;
HANDLE hHeaderThread;
DWORD dwRecvThreadId;
DWORD dwSendThreadId;
DWORD dwHeaderThreadId;
hHeaderThread = CreateThread(NULL,0,headerfunc,"1",0,&dwHeaderThreadId);
for (int mf=2; mf<25; mf++) {
std::cout<<"\n";
}
hSendThread = CreateThread(NULL,0,sendfunc,"1",0,&dwSendThreadId);
// Accept a client socket
for (int sock=1; sock<100; sock++) {
ClientSocket = accept(ListenSocket, NULL, NULL);
char sockprint[80];
char sockchar[4];
itoa(sock,sockchar,10);
strcpy(sockprint,"Client ");
strcat(sockprint,sockchar);
strcat(sockprint," connected.");
printm(sockprint);
GoToXY(0,23);
if (ClientSocket == INVALID_SOCKET) {
printm("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
client[sock].cs=ClientSocket;
client[sock].con=true;
lastclient=clientnumber;
clientnumber++;
currentclient=clientnumber;
hRecvThread = CreateThread(NULL,0,recvfunc,"1",0,&dwRecvThreadId);
}
// shutdown the connection since we're done
mshutdown();
std::cin.ignore();
return 0;
}
int printm(char *inp, DWORD color) {
HANDLE hOut;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hOut,
color);
printm(inp);
SetConsoleTextAttribute(hOut, 0 |
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
return 0;
}
int printm(char *inp) {
CONSOLE_SCREEN_BUFFER_INFO SBInfo;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hOut, &SBInfo);
int xx = SBInfo.dwCursorPosition.X;
int yy = SBInfo.dwCursorPosition.Y;
GoToXY(0,22);
std::cout<<inp<<"\n";
scroll();
GoToXY(xx,yy);
return 1;
}
int msend(char msendbuf[512]) // Send a message
{
if (strncmp(msendbuf,"Server> /exit",(strlen(msendbuf))) == 0) {
mexit();
}
if (strncmp(msendbuf,"Server> /set_client",19) == 0) {
int nm=atoi(&msendbuf[20]);
currentclient=nm;
ClientSocket=client[nm].cs;
char sockchar[4];
itoa(ClientSocket,sockchar,10);
char sockprint[80];
strcpy(sockprint,"New Socket: ");
strcat(sockprint,sockchar);
printm(sockprint);
char clientprint[80];
strcpy(clientprint,"Client: ");
strcat(clientprint,&msendbuf[20]);
printm(clientprint);
}
if (strncmp(msendbuf,"Server> /list_clients",(strlen(msendbuf))) == 0) {
printm("Clients:",FOREGROUND_RED);
for (int cm=1; cm < 100; cm++) {
int cn=client[cm].cs;
if (cn>0) {
char cli[80];
char cmchar[4];
char cnchar[80];
itoa(cn,cnchar,10);
itoa(cm,cmchar,10);
strcpy(cli,cmchar);
strcat(cli," ");
strcat(cli,cnchar);
strcat(cli," ");
strcat(cli,client[cm].ip.c_str());
strcat(cli," ");
strcat(cli,client[cm].name.c_str());
printm(cli,FOREGROUND_RED);
}
else {
break;
}
}
}
if (strncmp(msendbuf,"Server> /test",(strlen(msendbuf))) == 0) {
char ipcon[500];
*ipcon=(system("ipconfig"));
}
if (strncmp(msendbuf,"Server> /help",(strlen(msendbuf))) == 0) {
printm("Type /help for help or:");
printm("/set_client [client number]");
printm("/list_clients");
}
int iResult3 = send( ClientSocket, msendbuf, 512, 0 );
if (iResult3 == SOCKET_ERROR) {
printm("send failed with error: %d\n", WSAGetLastError());
return 1;
}
}
char* mrecv(bool show) //Recieve a message
{
int iResult2 = recv(ClientSocket, recvbuf, 512, 0);
if (iResult2 > 0) {
if ((strncmp(recvbuf,"/",1)) != 0) {
printm(recvbuf);
}
if (strncmp(recvbuf,"/ip",3) == 0) {
client[clientnumber].ip=&recvbuf[4];
char prin[80];
strcpy(prin,"client[clientnumber].ip: ");
strcat(prin,client[clientnumber].ip.c_str());
printm(prin,FOREGROUND_BLUE);
}
if (strncmp(recvbuf,"/name",5) == 0) {
client[clientnumber].name=&recvbuf[6];
char prin2[80];
strcpy(prin2,"client[clientnumber].name: ");
strcat(prin2,client[clientnumber].name.c_str());
printm(prin2,FOREGROUND_GREEN | FOREGROUND_BLUE);
}
if (strncmp(recvbuf,"/alert",5) == 0) {
char *message=&recvbuf[7];
char prin2[80];
strcpy(prin2,client[clientnumber].name.c_str());
strcat(prin2,": ");
strcat(prin2, message);
printm(prin2,FOREGROUND_RED);
}
if (strncmp(recvbuf,"Client> /alert",14) == 0) {
char *message=&recvbuf[15];
char prin2[80];
strcpy(prin2,client[clientnumber].name.c_str());
strcat(prin2,": ");
strcat(prin2, message);
printm(prin2,FOREGROUND_RED);
}
}
else if (iResult2 == 0) {
printf("Connection closing...\n");
closesocket(ClientSocket);
WSACleanup();
return "1";
}
else {
printm("recv failed with error: %d\n", WSAGetLastError());
printm("Client must have disconnected. Please select a new client.");
return "1";
}
return recvbuf;
}
int minitialize() //initialize the winsock server
{
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printm("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printm("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printm("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printm("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printm("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
unsigned long b=1;
ioctlsocket(ClientSocket,FIONBIO,&b);
}
int mshutdown() //shutdown the server
{
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printm("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
void GoToXY(int column, int line)
{
// Create a COORD structure and fill in its members.
// This specifies the new position of the cursor that we will set.
COORD coord;
coord.X = column;
coord.Y = line;
// Obtain a handle to the console screen buffer.
// (You're just using the standard console, so you can use STD_OUTPUT_HANDLE
// in conjunction with the GetStdHandle() to retrieve the handle.)
// Note that because it is a standard handle, we don't need to close it.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Finally, call the SetConsoleCursorPosition function.
if (!SetConsoleCursorPosition(hConsole, coord))
{
// Uh-oh! The function call failed, so you need to handle the error.
// You can call GetLastError() to get a more specific error code.
// ...
return;
}
}
int scroll( void )
{
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctScrollRect, srctClipRect;
CHAR_INFO chiFill;
COORD coordDest;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdout == INVALID_HANDLE_VALUE)
{
printf("GetStdHandle failed with %d\n", GetLastError());
return 1;
}
// Get the screen buffer size.
if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
{
printf("GetConsoleScreenBufferInfo failed %d\n", GetLastError());
return 1;
}
// The scrolling rectangle
srctScrollRect.Top = 1;
srctScrollRect.Bottom = 22;
srctScrollRect.Left = 0;
srctScrollRect.Right = csbiInfo.dwSize.X - 1;
// The destination for the scroll rectangle is one row up.
coordDest.X = 0;
coordDest.Y = 0;
// The clipping rectangle
srctClipRect.Top = 2;
srctClipRect.Bottom = 22;
srctClipRect.Left = 0;
srctClipRect.Right = csbiInfo.dwSize.X - 1;
// Fill the bottom row with blanks.
chiFill.Attributes = FOREGROUND_RED;
chiFill.Char.AsciiChar = (char)' ';
// Scroll up one line.
if(!ScrollConsoleScreenBuffer(
hStdout, // screen buffer handle
&srctScrollRect, // scrolling rectangle
&srctClipRect, // clipping rectangle
coordDest, // top left destination cell
&chiFill)) // fill character and color
{
printf("ScrollConsoleScreenBuffer failed %d\n", GetLastError());
return 1;
}
return 0;
}
int mexit()
{
msend("/server_closed");
mshutdown();
exit(0);
}
Turns out it was the recursive calling in my "sendfunc" thread that tripped me up.
Specifically,
if (msend(msendbuf)==1) {
"Client must have disconnected. Please select a new client.";
sendfunc("1");
}
Because I continued to call "sendfunc" from itself, it caused the stack overflow.
So, for anyone else having these problems, watch for overkill recursive function calls.
I simply removed my sending function and I was good to go.
The HSL stream is divided into multiple ts files, now I want to save these files and the m3u8 file to local disk in source code by calling ffmpeg APIs.
Does ffmpeg support this function? If so how to implement the function? Otherwise, can anyone give me some suggestions about how to achieve this goal?
Try this from videohelp please.
ffmpeg -i http://hls.twit.tv:1935/flosoft/smil:twitStream.smil/playlist.m3u8 -t 30 -c copy output1.mkv
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <time.h>
#include <curl/curl.h>
#include <direct.h>
#include <stdbool.h>
#include <errno.h>
char url[1000][100];
char channelname[1000][100];
char playlist[1000][50];
int totalURL;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
void downloadFile(char *link, char *outfilename) {
CURL *curl;
FILE *fp;
CURLcode res;
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename, "wb");
if (!fp) {
printf("File \"%s\" Can't open. Error: %d[%s]\n", outfilename, errno, strerror(errno));
curl_easy_cleanup(curl);
return;
}
curl_easy_setopt(curl, CURLOPT_URL, link);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
}
void getNewLink(int myIndex, FILE *fp) {
char line[1000], link[1000], outfilename[256];
int i, j = 0, len;
FILE *fp1;
int flag = 0;
memset(line, 0, sizeof(line));
while (!feof(fp)) {
if (fgets(line, 1000, fp) == 0) {
if (!feof(fp)) {
printf("Error in File reading.\n");
fclose(fp);
}
return;
}
len = strlen(line);
if (line[len - 1] == '\n') {
line[len - 1] = '\0';
len--;
}
for (i = 0; line[i] != '\0'; i++) {
if (line[i] != '\n' && line[i] != '\t') {
break;
}
}
if (line[i] == '\0') {
continue;
}
if (!strncmp(line, "#EXT-X-STREAM-INF:", 15)) {
flag = 1;
continue;
}
if(flag == 1){
flag = 0;
memset(link, 0, sizeof(link));
strcpy(link, url[myIndex]);
strcat(link, channelname[myIndex]);
strcat(link, "/");
strcat(link, line);
sprintf(outfilename, "chunk.m3u8");
downloadFile(link, outfilename);
fp1 = fopen(outfilename, "r");
if (!fp1) {
printf("File \"%s\" Can't open. Error: %d[%s]\n", outfilename, errno, strerror(errno));
continue;
}
getNewLink(myIndex, fp1);
fclose(fp1);
continue;
}
if (!strncmp(line, "#EXTINF:", 8)) {
flag = 2;
continue;
}
if (flag == 2) {
j++;
memset(link, 0, sizeof(link));
strcpy(link, url[myIndex]);
strcat(link, channelname[myIndex]);
strcat(link, "/");
strcat(link, line);
memset(outfilename, 0, sizeof(outfilename));
sprintf(outfilename, "%s\\chunk%d.ts", channelname[i], j);
downloadFile(link, outfilename);
flag = 0;
continue;
}
}
}
void readFile(char *filename) {
FILE *fp;
char line[1000];
int i, j, len;
memset(line, 0, sizeof(line));
fp = fopen(filename, "r");
if (!fp) {
printf("File \"%s\" Can't open. Error: %d[%s]\n", filename, errno, strerror(errno));
return;
}
while (!feof(fp)) {
if (fgets(line, 1000, fp) == 0) {
if (!feof(fp)) {
printf("Error in File reading.\n");
fclose(fp);
}
return;
}
len = strlen(line);
if (line[len - 1] == '\n') {
line[len - 1] = '\0';
len--;
}
for (i = 0; line[i] != '\0'; i++) {
if (line[i] != '\n' && line[i] != '\t') {
break;
}
}
if (line[i] == '\0') {
continue;
}
if (strncmp(line, "http", 4)) {
printf("Ignoring comment line.\n");
continue;
}
if (!strncmp(line, "http", 4)) {
for (j = 0; i < 100 && j < 100 && line[i] != '\t' && line[i] != '\0'; i++, j++) {
url[totalURL][j] = line[i];
}
url[totalURL][j] = '\0';
printf("url: %s\t", url[totalURL]);
}
for (j = 0, ++i; j < 100 && line[i] != '\t' && line[i] != '\0'; i++, j++) {
channelname[totalURL][j] = line[i];
}
channelname[totalURL][j] = '\0';
printf("%s\t", channelname[totalURL]);
for (j = 0, ++i; j < 50 && line[i] != '\t' && line[i] != '\0'; i++, j++) {
playlist[totalURL][j] = line[i];
}
playlist[totalURL][j] = '\0';
printf("%s\n", playlist[totalURL]);
totalURL++;
}
}
int main() {
FILE *fp;
char link[200];
int i;
char outfilename[FILENAME_MAX];
//analyzer file format should be like this: "http://devimages.apple.com/iphone/samples/ bipbop bipbopall.m3u8"
// http_link\tsub_path(OR some folder)\t*.m3u8
readFile("analyzer.txt");
printf("\n\n\n");
for (i = 0; i < totalURL; i++) {
memset(link, 0, sizeof(link));
strcpy(link, url[i]);
strcat(link, channelname[i]);
strcat(link, "/");
strcat(link, playlist[i]);
printf("URL: %s\n", link);
mkdir(channelname[i]);
memset(outfilename, 0, sizeof(outfilename));
sprintf(outfilename, "%s\\%s", channelname[i], playlist[i]);
printf("outputfile: %s\n", outfilename);
downloadFile(link, outfilename);
fp = fopen(outfilename, "r");
if (!fp) {
printf("File \"%s\" Can't open. Error: %d[%s]\n", outfilename, errno, strerror(errno));
break;
}
getNewLink(i, fp);
fclose(fp);
}
return 0;
}
If I compile my code in gcc 4.6, it works. However if I compile on gcc 4.7 (or newer), I get segmentation fault.
By the way, my code should analyze a html file and say if it's correct, all done using a stack.
I'm compiling with gcc -Wall *.c -o EXE
Running with ./EXE site.html
gdb says:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7abeb9a in getc () from /lib/x86_64-linux-gnu/libc.so.6
my main.c
#include <stdio.h>
#include <string.h>
#include "stack.h"
int readFile(char * nome, int m, int n, char out[m][n])
{
char temp1[1];
char temp2[50];
int i= 0;
char in;
FILE * site = fopen(nome, "r");
if(site == NULL) printf("\nArquivo não abriu");
//in = (char)fgetc (site);
//printf("%c", in);
do
{
in = (char)fgetc (site);
//printf("%c", in);
//if(in == EOF) break;
if(in == '<')
{
strcpy(temp2, "");
while(1)
{
in = (char)fgetc (site);
if(in == EOF || in == '>' || in == ' ') break;
sprintf(temp1, "%c", in);
printf("%c", in);
strcat(temp2, temp1);
}
if(
strcmp(temp2, "!DOCTYPE") == 0
||strcmp(temp2, "p") == 0
|| strcmp(temp2, "br") == 0
|| strcmp(temp2, "input") == 0
|| strcmp(temp2, "img") == 0
|| strcmp(temp2, "frame") == 0
|| strcmp(temp2, "li") == 0
)
{
}
else
{
strcpy(out[i], temp2);
printf("\nEncontrou %s", temp2);
i++;
}
}
}
while(in != EOF);
fclose (site);
return i;
}
int main(int argc, char * argv[])
{
if (argc != 2)
{
printf("\nColoque algum arquivo HTML na entrada do programa\n\n");
return(-1);
}
stack_p verificador = NULL;
char out[1000][1000];
char aux[50];
int i = 0;
int quant;
if(create(&verificador, 50 * sizeof(char)) == SUCESS)
{
quant = readFile(argv[1], 1000, 1000, out);
}
else return -1;
printf("\n\n");
for(i = 0; i< quant; i++)
{
if(out[i][0] != '/')
{
push(verificador,(void *) &out[i]);
printf("\n Empilhou %s", out[i]);
}
else if( out[i][0] == '/' )
{
searchTop(verificador,(void *) &aux);
//printf("\n no topo esta %s", aux);
if( strcmp(aux, &out[i][1]) == 0 )
{
pop(verificador);
printf("\n desempilhou %s", aux);
}
else
{
printf("\n ERRO: ");
printf("Esperava /%s, mas recebeu %s \n", aux, out[i] );
return -1;
}
}
printf("\n\n");
}
printf("\nO arquivo está correto!!\n\n");
return 0;
}
my stack.h
#include <stdlib.h>
#include <string.h>
#define FREE 0
#define BUSY 1
#define FAILED 0
#define SUCESS 1
#define TRUE 1
#define FALSE 0
#define EMPTY -1
#define YES 1
#define NO 0
typedef struct stack *stack_p, **stack_pp;
int create(stack_pp crtStack, int packSize);
void kill(stack_pp crtStack);
int searchTop(stack_p crtStack, void *reader);
int push(stack_p crtStack, void *new);
int pop(stack_p crtStack);
int length_stack(stack_p crtStack);
my privateDataStack.h
#include "stack.h"
typedef struct node
{
void *data;
struct node *next;
}node;
typedef struct stack
{
int packSize;
node* top;
}stack;
my stack.c
#include "privateDataStack.h"
#include <stdio.h>
#include <unistd.h>
/*--------------------------------------------------------------------*/
int create(stack_pp crtStack, int packSize)
{
if(( (*crtStack) =(stack_p) malloc(sizeof(stack)) ) == NULL)
{
return FAILED;
}
else
{
(*crtStack)->packSize = packSize;
(*crtStack)->top = NULL;
return SUCESS;
}
}
/*--------------------------------------------------------------------*/
void kill(stack_pp crtStack)
{
(**crtStack).top = NULL;
}
/*--------------------------------------------------------------------*/
int push(stack_p crtStack, void *new)
{
node *myNode;
if((myNode = (node*) malloc(sizeof(node)) ) == NULL)
{
return FAILED;
}
else
{
if((myNode->data = (void*) malloc(crtStack->packSize))
== NULL)
{
free(myNode);
return FAILED;
}
else
{
memcpy(myNode->data, new, crtStack->packSize);
myNode->next = crtStack->top;
crtStack->top = myNode;
return SUCESS;
}
}
}
/*--------------------------------------------------------------------*/
int pop(stack_p crtStack)
{
if( (*crtStack).top == NULL )
{
return FAILED;
}
else
{
crtStack->top = crtStack->top->next;
return SUCESS;
}
}
/*--------------------------------------------------------------------*/
int searchTop(stack_p crtStack, void *reader)
{
if(crtStack->top != NULL)
{
memcpy(reader, crtStack->top->data,
crtStack->packSize);
return SUCESS;
}
else
{
return FAILED;
}
}
int length_stack(stack_p crtStack)
{
int cont = 0;
node *aux;
if(crtStack->top != NULL)
{
cont++;
aux = crtStack->top;
while(aux->next != NULL)
{
aux = (node*)(aux->next);
cont ++;
}
}
return cont;
}
some html to test
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
The content of the document......
</body>
</html>
Thank you!!!!
In your function readFile(), this here:
char temp1[1];
/* ... */
sprintf(temp1, "%c", in);
... is triggering a buffer overflow.