I use the lines of code below (not that important for my question) to retrieve the current status of the existing network adapters. See the comment marked "HERE".
This works fine and it prints this text:
But I like to use a Callback or similar in C instead of my current code. I like to know if there is a way Windows 7 can alarm me, if the OperationStatus of one of my network adapters has changed? My problem is I dont know how to start.
#include <stdafx.h>
#include <winsock2.h>
#include <iptypes.h>
#include <iphlpapi.h>
#include <windows.h>
#include <iostream>
const ULONG MAX_BUFFER_SIZE = 15000;
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
int _tmain(int argc, _TCHAR* argv[])
{
PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL;
ULONG bufferSize = MAX_BUFFER_SIZE;
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(bufferSize);
GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddresses, & bufferSize);
do{
std::wcout<<"Name:\t\t\t "<<pAdapterAddresses->Description<<std::endl;
std::cout<<"OperationStatus:\t "<<pAdapterAddresses->OperStatus<<std::endl;
//HERE: prints network adapter status
if(pAdapterAddresses->Next != 0){
pAdapterAddresses = pAdapterAddresses->Next;
std::cout<<"\n";}
} while(pAdapterAddresses->Next != 0);
std::cin.get();
return 0;
}
Related
I am trying to run some code based on this libaio sample:
https://oxnz.github.io/2016/10/13/linux-aio/#example-1
I added the O_DIRECT flag according to libaio's documentation.
It seems to work inside my ubuntu 16.04 desktop machine (hello is written to /tmp/test).
However, when I compile and run the same sample inside a docker container nothing is written to the file. when running inside gdb I can see that an event is read by io_getevents and the result is set to -22 (EINVAL).
Any ideas?
This is my modified code
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <libaio.h>
int main() {
io_context_t ctx;
struct iocb iocb;
struct iocb * iocbs[1];
struct io_event events[1];
struct timespec timeout;
int fd;
fd = open("/tmp/test", O_WRONLY | O_CREAT | O_DIRECT) ;
if (fd < 0) err(1, "open");
memset(&ctx, 0, sizeof(ctx));
if (io_setup(10, &ctx) != 0) err(1, "io_setup");
const char *msg = "hello";
io_prep_pwrite(&iocb, fd, (void *)msg, strlen(msg), 0);
iocb.data = (void *)msg;
iocbs[0] = &iocb;
if (io_submit(ctx, 1, iocbs) != 1) {
io_destroy(ctx);
err(1, "io_submit");
}
while (1) {
timeout.tv_sec = 0;
timeout.tv_nsec = 500000000;
int ret = io_getevents(ctx, 0, 1, events, &timeout);
printf("ret=%d\n", ret);
if (ret == 1) {
close(fd);
break;
}
printf("not done yet\n");
sleep(1);
}
io_destroy(ctx);
return 0;
}
The filesystem inside the container is likely to be different to that of the host's filesystem (on modern setups is likely to be overlayfs but on older systems it could be aufs). For O_DIRECT on an open to work a device/filesystem has to at least "support" it (note the scare quotes) and it's likely your container's filesystem does not.
I'm writing a Memcached UDP client with libmemcached/memcached.h to send some arbitrary loads on Memcached server. I can send set requests in UDP but I'm unable to send get requests, here is the snippet I wrote for this!
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libmemcached/memcached.h>
#include <time.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <signal.h>
int main(int argc, char *argv[])
{
memcached_server_st *servers = NULL;
memcached_st *memc;
memcached_return rc;
char * res;
char *key= "kay";
int size = 1000;
char * value = malloc(size);
uint32_t flags;
size_t return_value_length;
char * ip = argv[2];
memset(value, 1, size);
memc = memcached_create(NULL);
servers= memcached_server_list_append(servers, ip, 11211, &rc);
rc = memcached_server_push(memc, servers);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, (uint64_t)1);
rc = memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint32_t)0);
if (rc == MEMCACHED_SUCCESS)
fprintf(stderr,"Key stored successfully\n");
else
fprintf(stderr,"Couldn't store key: %s\n",memcached_strerror(memc, rc));
while ( true)
{
res = memcached_get(memc, key, strlen(key), &return_value_length, &flags, &rc);
free(res);
if(rc != MEMCACHED_SUCCESS)
{
fprintf(stderr, "%s\n", memcached_strerror(memc, rc));
}
}
memcached_free(memc);
return 0;
Actually, get requests always are unsuccessful!!! I also monitored the packets with Wireshark the client doesn't even send any packet out to the server!!! And it just got failed while sending get request.
Is there any obvious problem in the code which I couldn't see?
Thank you
According to the manpage of memcached_behaviour_set():
The following operations will return MEMCACHED_NOT_SUPPORTED when
executed with the MEMCACHED_BEHAVIOR_USE_UDP enabled:
memcached_version(), memcached_stat(), memcached_get(),
memcached_get_by_key(), memcached_mget(), memcached_mget_by_key(),
memcached_fetch(), memcached_fetch_result(),
memcached_fetch_execute().
So indeed, memcached_get() does not work when the memcached-handle is set to UDP transport. You will have to use TCP for that.
Warning: I'm quite new to C and memory mgmt and all that stuff (coming from interpreted/JITed languages).
So I'm making a little library for creating TCP servers easily (as an exercise in network programming). An example of usage could look like the following:
#include <stdio.h>
#include "ohsimpletcp.h"
void echo(int socket_fd) {
char *message = malloc(100 * sizeof(char));
while (ost_receive(socket_fd, message, 100) > 0) {
ost_send(socket_fd, message);
}
}
int main() {
if (ost_serve(1337, echo) == -1) {
perror("An error occurred");
return 1;
}
return 0;
}
But my question is, for making this thing smoothly concurrent for a high number of clients, do I need to create a new process for every connected client in the backend? Or could I solve this with select() somehow?
ohsimpletcp.h:
#ifndef REG4IN_OST_H
#define REG4IN_OST_H 1
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int ost_serve(int port, void (*handler)(int socket_fd));
int ost_send(int socket_fd, char *message);
int ost_receive(int socket_fd, char *message, int length);
#endif
I am an embedded programmer and using a multithreaded application which is going to receive pixel data over serial line and display it in a window. I am using openCV's cvSetData() method to copy the data received over serial line and populate it to an openCV array. Also using the cvShowImage() function I am displaying the continuously updating pixel data( concept of displaying a video).
Here is a snippet from my code:
//-------------------------------------Start of code------------------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include "serial_comm_defines.h"
#include <opencv2/highgui/highgui.hpp>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
extern unsigned char array[COUNT_LIM];
IplImage *newimage;
img_disp_method(void)
{
cvSetData((CvArr*)newimage, (void*)array, 1556);
cvNamedWindow("Mywindow",CV_WINDOW_FREERATIO);
cvResizeWindow("Mywindow", 1556, 360);
cvShowImage("Mywindow",(CvArr*)newimage);
cvWaitKey(1);
}
void *serial_thread_method(void* my_fd)
{
clock_t start = 0, end = 0;
double time_taken = 0;
if ((int)my_fd<0)
printf("\nError opening device file\n");
else
{
printf("\nDevice file opened successfully\n");
if ( serial_config((int)my_fd) < 0)
printf("\nUnable to configure serial port\n");
else
{
printf("\nSerial port configured successfully\n");
for(;;)
{
start = clock();
serial_read((int)my_fd);
end = clock();
printf("\nTime taken:%f seconds\n", (double)((end-start)/CLOCKS_PER_SEC));
}
}
}
close ((int)my_fd);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t serial_read_thread;
int my_fd=0, i=0, temp=0, serial_thread_ret=0;
newimage = cvCreateImageHeader(cvSize(HEIGHT, WIDTH), IPL_DEPTH_8U, 0x01);
struct timeval my_value={0,10000};
struct timeval my_interval={0,10000};
struct itimerval my_timer={my_interval,my_value};
setitimer(ITIMER_REAL, &my_timer, 0);
signal(SIGALRM, img_disp_method);
my_fd = open_device_file((char**)argv);
if ( (serial_thread_ret = pthread_create(&serial_read_thread, NULL, serial_thread_method, (void*)my_fd) == 0))
fprintf(stdout, "\nSerial read thread created successfully\n");
else
perror("\nError creating serial read thread\n");
pthread_join(&serial_read_thread, NULL);
cvReleaseImageHeader(&newimage);
return NULL;
}
//----------------------------------------End of code--------------------------------------//
The code is compiling fine. But when I execute the binary it throws the following error. I also observed that if change the value of timer (value of my_value and my_interval) to anywhere greater than 30ms (30000) the code works just fine. Please explain what is happening.
Try using a virtual timer instead of a real timer.
Something like this
setitimer(SIGVTALRM, &my_timer, 0);
signal(SIGVTALRM, img_disp_method);
I want to do some CRC check in my own userspace programme. And I find that the kernel crypto lib is already in the system, and come with SSE4.2 support.
I tried to directly #include <linux/crc32c.h> and run gcc with -I/usr/src/linux/include/. However, it doesnot work.
Any way to use some kind of libcrc32c ?
You can use kernel crypto CRC32c (and other hash/cipher functions) from user-space via socket family AF_ALG on Linux:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
#include <sys/param.h>
#include <string.h>
#include <strings.h>
int
main (int argc, char **argv) {
int sds[2] = { -1, -1 };
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "hash",
.salg_name = "crc32c"
};
if ((sds[0] = socket(AF_ALG, SOCK_SEQPACKET, 0)) == -1 )
return -1;
if( bind(sds[0], (struct sockaddr *) &sa, sizeof(sa)) != 0 )
return -1;
if( (sds[1] = accept(sds[0], NULL, 0)) == -1 )
return -1;
char *s = "hello";
size_t n = strlen(s);
if (send(sds[1], s, n, MSG_MORE) != n)
return -1;
int crc32c = 0x00000000;
if(read(sds[1], &crc32c, 4) != 4)
return -1;
printf("%08X\n", crc32c);
return 0;
}
If you're hashing files or socket data you can speed it up using zero-copy approach to avoid kernel -> user-space buffer copy with sendfile and/or splice.
Happy coding.