void main()
{
HANDLE h1,h2,h3;
uint8 data;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ;
CreateSocket();
XCP_FN_TYPE Xcp_Initialize( );
while(1)
{
data = recv(fd, recv_data, 99, 0);
if (data == SOCKET_ERROR) {
printf("recv failed with error %d\n", WSAGetLastError());
}
else
{
pChunkData = &recv_data;
chunkLen = sizeof(pChunkData);
XcpIp_RxCallback ((uint16) chunkLen, (char*) pChunkData, (uint16) port);
}
}
h1=TimerTask(2,TASK1,&Task2ms_Raster);
h2=TimerTask(10,TASK2,&Task10ms_Raster);
h3=TimerTask(100,TASK3,&Task100ms_Raster);
XCP_FN_TYPE XcpIp_OnTcpCxnClosed( port );
}
I have created the server socket and recieving data from the client via the ip address and the port number. I have to run the timer task in parallel with the recieve data from the socket.The function definition of create scoket and TimerTask functionality is not shown. So could anyone please help me how to run the timer task parallel to it ??
Related
I want to write some code using multithreading and sockets to create a server and this server can accept four connections (clients)
How can I receive and send data to the client? How do I know from which client I receive my data?
This the code:
if (listen(serverSocket, 20) == 0)
printf("Listening\n");
else
printf("Error\n");
int i = 0;
while (1){
addr_size = sizeof(serverStorage);
//accept
newSocket = accept(serverSocket,
(struct sockaddr*)&serverStorage,
&addr_size);
int type = 0;
recv(newSocket,
&type, sizeof(type), 0);
if (type == 1) {
// Creater readers thread
if (pthread_create(&readerthreads[i++], NULL,
reader, &newSocket)
!= 0)
// Error in creating thread
printf("Failed to create thread\n");
}
else if (type == 2) {
// Create writers thread
if (pthread_create(&writerthreads[i++], NULL,
writer, &newSocket)
!= 0)
// Error in creating thread
printf("Failed to create thread\n");
}
if (i >= 5) {
// Update i
i = 0;
while (i < 5) {
// Suspend execution of
// the calling thread
// until the target
// thread terminates
pthread_join(writerthreads[i++],
NULL);
pthread_join(readerthreads[i++],
NULL);
}
// Update i
i = 0;
}
}
How can I modify it to receive data from a specific client and send also to specific client?
there is the method send(); and recv(); but I don't know How the variable NewSocket tell to which client is sending it
const struct sigevent *intHandler(void *arg, int id)
{
start_clock = ClockCycles();
//printf("start clock: %lld\n", start_clock);
return(&event);
}
int ConfigureISR()
{
// Get IO privilege
//
ThreadCtl( _NTO_TCTL_IO, 0 );
//
// Setup COID and event
chid = ChannelCreate( 0 );
SIGEV_INTR_INIT( &event);
interruptID = InterruptAttach(7, intHandler, NULL, 0, 0);
if (interruptID == -1)
{
fprintf(stderr, "can't attach to IRQ\n");
perror (NULL);
exit (EXIT_FAILURE);
}
InterruptWait(0, NULL);
end_clock = ClockCycles();
// printf("end clock: %lld\n", end_clock);
//microseconds
InterruptLatency = (uint32) ((end_clock - start_clock)*1000000/(SYSPAGE_ENTRY(qtime)->cycles_per_sec));
printf("microseconds: %ld\n", InterruptLatency);
measurements[17] = InterruptLatency;
return (EXIT_SUCCESS);
}
int main()
{
ConfigureISR();
// my socket code here to receive data from client.
}
I created an interrupt handler in c for QNX operating system.
my task: kernel should call this interrupt handler, whenever there is a data on the udp layer. I am calculating the interrupt latency in the above code.
CLIENT is sending data and server (above code) is receiving the data from client and sending back the response.
The above code is not interrupted everytime, when ever it receives data on the udp layer. what could be the mistake in the above ?? could someone please help me in that ??
int CreateSocket()
{
// SOCKET connectedSocket;
// SOCKADDR_IN addr;
// char buf[256];
// char buf2[300];
// Winsock starten
HANDLE h1,h2,h3;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ;
long rc;
SOCKET acceptSocket;
rc=startWinsock();
if(rc!=0)
{
printf("Fehler: startWinsock, fehler code: %d\n",rc);
return 1;
}
else
{
printf("Winsock gestartet!\n");
}
// Socket erstellen
acceptSocket=socket(AF_INET,SOCK_STREAM,0);
if(acceptSocket==INVALID_SOCKET)
{
printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Socket erstellt!\n");
}
memset(&addr,0,sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
if(rc==SOCKET_ERROR)
{
printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Socket an port %d gebunden\n",port);
}
rc=listen(acceptSocket,10);
if(rc==SOCKET_ERROR)
{
printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("acceptSocket ist im listen Modus....\n");
}
connectedSocket=accept(acceptSocket,NULL,NULL);
if(connectedSocket==INVALID_SOCKET)
{
printf("Fehler: accept, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Neue Verbindung wurde akzeptiert!\n");
// strcpy(buf,"Hallo wie gehts?");
// rc=send(acceptSocket,buf,9,0);
// Daten austauschen
while(rc!=SOCKET_ERROR)
{
rc=recv(connectedSocket,buf,256,0);
if(rc==0)
{
printf("Server hat die Verbindung getrennt..\n");
break;
}
if(rc==SOCKET_ERROR)
{
printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
break;
}
XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
h1=TimerTask(2,TASK1,&Task2ms_Raster);
h2=TimerTask(10,TASK2,&Task10ms_Raster);
h3=TimerTask(100,TASK3,&Task100ms_Raster);
}
}
closesocket(acceptSocket);
closesocket(connectedSocket);
XcpIp_OnTcpCxnClosed((uint16) port );
WSACleanup();
return 0;
}
The above code is a server code and accepts a connection from the client via the ip address and port number. I am accepting the connection and recieving the data from the client. I want to run the TimerTask in the background, timer task is calling a function called TASK1, TASK2 and TASK3 for every 2ms , 10ms and 100ms. So how to run those function in the background. Please someone help me.
If you want to make things run in parallel, you can use threads for Multithreading, or forks for multiprocessing.
Here's an example for multithreading in c:
#include <pthread.h>
void handleClient(SOCKET clientSock)
{
... read and write ...
}
int main()
{
... prepare the server ...
... listen on socket ...
for(;;){
connectedSocket=accept(acceptSocket,NULL,NULL);
pthread_t *tid = malloc( sizeof(pthread_t) );
pthread_create( &tid, NULL, handleClient, connectSocket );
... test, if the server should be killed, and break the loop ...
}
}
Notice, that this is a very minimalistic example. You should also care about "collecting your threads" with pthread_join( tid, NULL );, thus you have to store all your pthread_t-Variables inside an Array or a linked list.
Since posting my original question about enumerating multiple devices, I have discovered the reason multiple enumerations were not occuring; The devices all have the same deviceID. With this discovery, I would like to pose a new question, hopfully leading to a work around...
[EDIT]
The new question:
Is there a method, other than unique enumeration, available to get dedicated sockets for each of many devices, when all devices use the same deviceID?
Scenario and rules:
I am developing an application on Windows 7, using Microsoft SDK and an ANSI C compiler. The application design requires it to detect any IrDA device in range, connect using sockets, and communicate. Communication will be to multiple devices through multiple IrDA dongles (one dongle per device), each dongle is connected to the PC via USB. Note: Using virtual COM ports is to be avoided.
The objective: connect each device to its own socket providing an exclusive communication channel between it and the application software.
illustrations and source code (for enumeration of IrDA devices) are below.
[EDIT]
Illustration 1: Overall scenario:
Illustration 2: From Device Manager:
Illustration 3: Properties of each 'found' IrDA device:
Here is the code to enumerate two or more unique IrDA devices: (tested and working well)
//Adapted from: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738544(v=vs.85).aspx
#include <winsock2.h>
#include <ws2tcpip.h>
#include <af_irda.h>
#include <stdio.h>
#include <windows.h>
// link with Ws2_32.lib
char* iGetLastErrorText(DWORD nErrorCode);
int __cdecl main(void)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
int i, tries = 0;
DWORD dwError;
SOCKET Sock = INVALID_SOCKET;
#define DEVICE_LIST_LEN 10
SOCKADDR_IRDA DestSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };
unsigned char DevListBuff[sizeof (DEVICELIST) -
sizeof (IRDA_DEVICE_INFO) +
(sizeof (IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof (DevListBuff);
PDEVICELIST pDevList;
pDevList = (PDEVICELIST) & DevListBuff;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
Sock = socket(AF_IRDA, SOCK_STREAM, 0);
if (Sock == INVALID_SOCKET) {
dwError = WSAGetLastError();
printf
("socket failed trying to create an AF_IRDA socket with error %d\n",
dwError);
if (dwError == WSAEAFNOSUPPORT) {
printf("Check that the local computer has an infrared device\n");
printf
("and a device driver is installed for the infrared device\n");
}
WSACleanup();
return 1;
}
pDevList->numDevice = 0;
while((pDevList->numDevice < 2)&&( tries++ < 3 ))
{
// Sock is not in connected state
iResult = getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *) pDevList, &DevListLen);
if (iResult == SOCKET_ERROR) {
printf("getsockopt failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
iResult = closesocket(Sock);
if(iResult == SOCKET_ERROR)
{
printf("closesocket failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
WSACleanup();
getchar();
return 1;
}
WSACleanup();
getchar();
return 1;
}
if (pDevList->numDevice == 0) {
// no devices discovered or cached
// not a bad idea to run a couple of times
printf("No IRDA devices were discovered or cached\n");
} else {
// one per discovered device
printf("pDevList->numDevice = %d\n", pDevList->numDevice);
for (i = 0; i < (int) pDevList->numDevice; i++) {
printf( "irdaCharSet: %d\nHints1: %d\nHints2: %d\nDeviceID: %x\nDeviceName: %s\n\n",
pDevList->Device[i].irdaCharSet,
pDevList->Device[i].irdaDeviceHints1,
pDevList->Device[i].irdaDeviceHints2,
pDevList->Device[i].irdaDeviceID,
pDevList->Device[i].irdaDeviceName);
// typedef struct _IRDA_DEVICE_INFO
// {
// u_char irdaDeviceID[4];
// char irdaDeviceName[22];
// u_char irdaDeviceHints1;
// u_char irdaDeviceHints2;
// u_char irdaCharSet;
// } _IRDA_DEVICE_INFO;
// pDevList->Device[i]. see _IRDA_DEVICE_INFO for fields
// display the device names and let the user select one
}
}
}
// assume the user selected the first device [0]
memcpy(&DestSockAddr.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0],4);
iResult = connect(Sock, (const struct sockaddr *) &DestSockAddr, sizeof (SOCKADDR_IRDA));
if (iResult == SOCKET_ERROR)
{
if (iResult == SOCKET_ERROR) {
printf("connect failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
iResult = closesocket(Sock);
if(iResult == SOCKET_ERROR)
{
printf("closesocket failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
WSACleanup();
getchar();
return 1;
}
WSACleanup();
getchar();
return 1;
}
}
else
{
printf("connect to first IRDA device was successful\n");
}
getchar();
WSACleanup();
return 0;
}
char* iGetLastErrorText(DWORD nErrorCode)
{
char* msg;
// Ask Windows to prepare a standard message for a GetLastError() code:
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, nErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
// Return the message
if (!msg)
return("Unknown error");
else
return(msg);
}
Closing the loop on this old question: The short answer is no, There is not another method.
IrDA sockets are created and in my case, in Windows 7, enumerated based on a Windows interrogation of any and all IrDA signals active and in range. The enumeration process stores data for each unique Device ID (specifically, IrDA Dev id) it finds. If it sees 3 unique Device IDs, then data for each can be stored, and made available for a connection to be completed. Subsequently, for each connection made, separate conversations can be held with each of those devices. However, if the same three devices are active, and in range, but have identical Device IDs, Windows will only store data corresponding to that one ID, and only one connection can be made.
I have developed a chat server program using threads. In this program there are two threads:
One to receive data
One to send data
Both of the threads contain the infinite loop in order to continuously send and receive data. But when it is executed the thread for receiving data gets stuck in the loop.
The code of the server:
{
addr_len=sizeof(cli_addr);
cli_sock=accept(sock,(struct sockaddr *)&cli_addr,&addr_len);
if(cli_sock<0)
printf("\nConnetion Error\n");
else
printf("conneted\n");
status_s=pthread_create(&thread_s,NULL,send_data,&cli_sock);
if(status_s==0)
printf("sending");
status_r=pthread_create(&thread_r,NULL,recieve_data,&cli_sock);
if(status_r==0)
printf("recieving");
}
}
void *recieve_data(void *num)
{
int *sock_r=(int *) num;
int sock=*sock_r;
char msg[50];
while(1)
{
recv(sock_r,msg,sizeof(msg),0);
if(strcmp(msg,"exit")==0)
{
break;
}
printf("recieved data:");
recv(sock_r,msg,sizeof(msg),0);
printf("\n%s",msg);
}
}
void *send_data(void *num)
{
int *sock_s=(int *) num;
int sock=*sock_s;
char msg[50];
while(1)
{
gets(msg);
//printf("sending data");
if(strcmp(msg,"exit")==0)
{
break;
}
send(sock_s,msg,sizeof(msg),0);
}
send(sock,msg,sizeof(msg),0);
}
Would be better if control commands like "exit" are int based.
Also, receive data doesn't handle peer connection closure status. Ex:
Copied from here.
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );