LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-02-2006, 12:22 PM   #1
qinglau
LQ Newbie
 
Registered: Mar 2006
Posts: 10

Rep: Reputation: 0
C socket programming Help!


Hello All,

I want to build a TCP socket function which based on a event application.
I almost finished all the function except a small problem.

Here is the problem, The client can connect my application call evtest through port 7046. After the connection is built, the evtest can send out the command string to the client.

But if the client closes the connection and my evtest will shut down also. It said that "Send, connection reset by peer."

What I really want my evtest can always active, the client side can always connect to my evtest even after close the connection.

To more clearly present what I want, I want the evtest application can always accept the outside connection and send out the command to them. Even the client break out connection, they can simply connect to my evtest application without disturb my evtest.

Thank you for reading. Sorry for my english.

------------------------------------------------------------------
#include <stdint.h>
#include <linux/input.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

//Add the networking part include files
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
/*/
/*#include <string.h>
* Replaced inline event and code definitions with an external header that
* has been automatically generated from the /usr/include/linux/input.h
* by the mkheader.pl utility
*/
#include "evtest.h"
#include <string.h>
#ifndef EV_SYN
#define EV_SYN 0
#endif
#include <string.h>

char **names[EV_MAX + 1] = {
[0 ... EV_MAX] = NULL,
[EV_SYN] = events, [EV_KEY] = keys,
[EV_REL] = relatives, [EV_ABS] = absolutes,
[EV_MSC] = misc, [EV_LED] = leds,
[EV_SND] = sounds, [EV_REP] = repeats,
[EV_FF] = forcefeedback, [EV_FF_STATUS] = ffstatus,
};

char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };

#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)

#define MYPORT 7046 // the port users will be connecting to
#define BACKLOG 10

//Struct for socket handler
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}

int main (int argc, char **argv) {

int fd, rd, i, j, k;
struct input_event ev[64];
int version;
unsigned short id[4];
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
char name[256] = "Unknown";
int abs[5];


// Network parameters
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char *messageCommand; // A message pointer will pointer the command string
messageCommand = (char *)malloc(5 + 1 + 5 + 1 + 5 + 1 + 2);
char *testMessage="Send the test string out!";



/* All about networking part
*
*/

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}

my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

// What port am I on
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

/*
* In here, it starts to send the event to user
*/
if (argc < 2) {
printf("Usage: evtest /dev/input/eventX\n");
printf("Where X = input device number\n");
return 1;
}

if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
perror("evtest");
return 1;
}

if (ioctl(fd, EVIOCGVERSION, &version)) {
perror("evtest: can't get version");
return 1;
}

printf("Input driver version is %d.%d.%d\n",
version >> 16, (version >> 8) & 0xff, version & 0xff);

ioctl(fd, EVIOCGID, id);
printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

ioctl(fd, EVIOCGNAME(sizeof(name)), name);
printf("Input device name: \"%s\"\n", name);

memset(bit, 0, sizeof(bit));
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
printf("Supported events:\n");

for (i = 0; i < EV_MAX; i++) {
if (test_bit(i, bit[0])) {
printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
if (!i) continue;
ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
for (j = 0; j < KEY_MAX; j++) {
if (test_bit(j, bit[i])) {
printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
if (i == EV_ABS) {
ioctl(fd, EVIOCGABS(j), abs);
for (k = 0; k < 5; k++)
if ((k < 3) || abs[k])
printf(" %s %6d\n", absval[k], abs[k]);
}
}
}
}
}

printf("Wait for connection");
printf("Testing ... (interrupt to exit)\n");
//Setup a sending message destination, new_fd is the address where send to
sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));


while (1) {

int sType=-1;
int sCode=-1;
int sValue=-1;

rd = read(fd, ev, sizeof(struct input_event) * 64);
if (rd < (int) sizeof(struct input_event)) {
printf("yyy\n");
perror("\nevtest: error reading");
return 1;
}


for (i = 0; i < rd / sizeof(struct input_event); i++) {
if (ev[i].type == EV_SYN) {
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
printf("Event: time %ld.%06ld, -------------- %s ------------\n",
ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
} else {
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
//Put into parameters
sType=ev[i].type;
sCode=ev[i].code;
sValue=ev[i].value;
sprintf(messageCommand, "%hd,%hd,%hd,\n\0", sType, sCode, sValue);

if (send(new_fd, messageCommand, strlen(messageCommand), 0) == -1)
{ perror("send");
close(new_fd);
exit(0);
}
}
}
}

free(messageCommand);
close(sockfd);
}

/* End */
 
Old 05-02-2006, 01:03 PM   #2
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Having read your description what immediately comes to mind is that you need to fork your server application.

You set up your server as a listening socket.
When a connection arrives you call fork to create a clone of the server process
The parent will close the connection and continue listening for more requests
The child will close the listening socket but retain and process the connection with the client.

That's the basic theory. For more do a google on: fork listening socket tutorial
 
Old 05-02-2006, 02:41 PM   #3
MichaelZ
Member
 
Registered: Mar 2006
Location: Austria
Distribution: Ubuntu Breezy 5.10
Posts: 32

Rep: Reputation: 15
Hello,

You can have a look at this thread:

http://www.linuxquestions.org/questi...d.php?t=438084

Wim Sturkenboom put a link to very useful examples.

Best wishes,
Michael
 
Old 05-02-2006, 03:08 PM   #4
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 34
Alternatively, you could run your server under inted (though doing it (the forking etc) yourself will be more efficient if you expect a lot of connections).
 
Old 05-03-2006, 09:25 AM   #5
qinglau
LQ Newbie
 
Registered: Mar 2006
Posts: 10

Original Poster
Rep: Reputation: 0
Hi Guys,

Thanks for the information.
I made it work now.
Thank you for graemef reminder. What I really Miss in the code, it is fork.
--------------------------------------------------------------------------------------

/*
* $RCSfile: evtest.c,v $
* Original Author...: Anthony Awtrey
* Version...........: $Revision: 1.1 $
* Last Modified By..: $Author: aawtrey $
* Last Modified.....: $Date: 2005/03/05 04:45:14 $
*
* Copyright 2005 I.D.E.A.L. Technology Corporation
* Based on event test example code Copyright (c) 1999-2000 Vojtech Pavlik
*
* Purpose:
* Report complete set of events from the /dev/input/event* devices
*
* NOTE: This program was modified to include all current event types,
* codes and values available from the 2.6.7 kernel's input.h file.
* A script called mkheader.pl was written to parse the contents of the
* input.h file to automate the process of creating the evtest.h file.
* This should make it easier to track future changes for the event
* device stream in the kernel.
*
* PEDANTIC BUILD INSTRUCTIONS:
* gcc -o evtest evtest.c
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#include <stdint.h>
#include <linux/input.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

//Add the networking part include files
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
/*/
/*#include <string.h>
* Replaced inline event and code definitions with an external header that
* has been automatically generated from the /usr/include/linux/input.h
* by the mkheader.pl utility
*/
#include "evtest.h"
#include <string.h>
#ifndef EV_SYN
#define EV_SYN 0
#endif
#include <string.h>

char **names[EV_MAX + 1] = {
[0 ... EV_MAX] = NULL,
[EV_SYN] = events, [EV_KEY] = keys,
[EV_REL] = relatives, [EV_ABS] = absolutes,
[EV_MSC] = misc, [EV_LED] = leds,
[EV_SND] = sounds, [EV_REP] = repeats,
[EV_FF] = forcefeedback, [EV_FF_STATUS] = ffstatus,
};

char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };

#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)

#define MYPORT 7046 // the port users will be connecting to
#define BACKLOG SOMAXCONN //10

//Struct for socket handler
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}

int main (int argc, char **argv) {

int fd, rd, i, j, k;
struct input_event ev[64];
int version;
unsigned short id[4];
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
char name[256] = "Unknown";
int abs[5];


// Network parameters
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char *messageCommand; // A message pointer will pointer the command string
messageCommand = (char *)malloc(5 + 1 + 5 + 1 + 5 + 1 + 2); //set the memory
//char *testMessage="Send the test string out!";


/* All about networking part
*
*/

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}

my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct


// What port am I on
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

/*
* In here, it starts to send the event to user
*/
if (argc < 2) {
printf("Usage: evtest /dev/input/eventX\n");
printf("Where X = input device number\n");
return 1;
}

if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
perror("evtest");
return 1;
}

if (ioctl(fd, EVIOCGVERSION, &version)) {
perror("evtest: can't get version");
return 1;
}

printf("Input driver version is %d.%d.%d\n",
version >> 16, (version >> 8) & 0xff, version & 0xff);

ioctl(fd, EVIOCGID, id);
printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

ioctl(fd, EVIOCGNAME(sizeof(name)), name);
printf("Input device name: \"%s\"\n", name);

memset(bit, 0, sizeof(bit));
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
printf("Supported events:\n");

for (i = 0; i < EV_MAX; i++) {
if (test_bit(i, bit[0])) {
printf(" Event type %d (%s)\n", i, events[i] ?events[i] : "?");
if (!i) continue;
ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
for (j = 0; j < KEY_MAX; j++) {
if (test_bit(j, bit[i])) {
printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
if (i == EV_ABS) {
ioctl(fd, EVIOCGABS(j), abs);
for (k = 0; k < 5; k++)
if ((k < 3) || abs[k])
printf(" %s %6d\n", absval[k], abs[k]);
}
}
}
}
}


#if 0
/*---Forever... ---*/
while (1)
{ int clientfd;
struct sockaddr_in client_addr;
socklen_t addrlen=sizeof(client_addr);

/*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

if (!fork())
{
/*---Echo back anything sent---*/
while (send(clientfd, /*buffer*/"t", 2, 0) != -1)
;
exit(0);
}

/*---Close data connection---*/
close(clientfd);
}

#endif


int connected;
printf("Wait for connection\n");
printf("Testing ... (interrupt to exit)\n");
while(1) // connection accept loop
{
//Setup a sending message destination, new_fd is the address where send to
sin_size = sizeof(struct sockaddr_in);
printf("waiting for connection...\n");
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);

printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));

pid_t pID = fork();
if (pID == 0)
{
printf("fork() child process\n");
// FORK START
close(sockfd); // sockfd is not needed in the child process

connected = 1;
while (connected) // data transfer loop
{
int sType=-1;
int sCode=-1;
int sValue=-1;

rd = read(fd, ev, sizeof(struct input_event) * 64);
if (rd < (int) sizeof(struct input_event))
{
printf("yyy\n");
perror("\nevtest: error reading");
return 1;
}

for (i = 0; i < rd / sizeof(struct input_event); i++)
{
printf("%d ", i);
if (ev[i].type == EV_SYN)
{
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
printf("Event: time %ld.%06ld, -------------- %s ------------\n",
ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
}
else
{
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
//Put into parameters
sType=ev[i].type;
sCode=ev[i].code;
sValue=ev[i].value;
sprintf(messageCommand, "%hd,%hd,%hd,\n", sType, sCode, sValue);

if (send(new_fd, messageCommand, strlen(messageCommand), 0) == -1)
{
printf("disconnected\n");
connected = 0;
break;
}
}// end else
} // end for loop
} //end while data transfer loop

close(new_fd);
// FORK END
exit(0);
} //end fork
else if (pID < 0)
printf("fork() failed\n");
else
{
printf("fork() parent process\n");
close(new_fd);
}

} //end while connection accept loop

close(sockfd);
// Free memory and close connection.
free(messageCommand);
close(sockfd);
}





/* End */
 
Old 05-03-2006, 09:26 AM   #6
qinglau
LQ Newbie
 
Registered: Mar 2006
Posts: 10

Original Poster
Rep: Reputation: 0
Hi Guys,

Thanks for the information.
I made it work now.
Thank you for graemef reminder. What I really Miss in the code, it is fork.
--------------------------------------------------------------------------------------

/*
* $RCSfile: evtest.c,v $
* Original Author...: Anthony Awtrey
* Version...........: $Revision: 1.1 $
* Last Modified By..: $Author: aawtrey $
* Last Modified.....: $Date: 2005/03/05 04:45:14 $
*
* Copyright 2005 I.D.E.A.L. Technology Corporation
* Based on event test example code Copyright (c) 1999-2000 Vojtech Pavlik
*
* Purpose:
* Report complete set of events from the /dev/input/event* devices
*
* NOTE: This program was modified to include all current event types,
* codes and values available from the 2.6.7 kernel's input.h file.
* A script called mkheader.pl was written to parse the contents of the
* input.h file to automate the process of creating the evtest.h file.
* This should make it easier to track future changes for the event
* device stream in the kernel.
*
* PEDANTIC BUILD INSTRUCTIONS:
* gcc -o evtest evtest.c
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#include <stdint.h>
#include <linux/input.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

//Add the networking part include files
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
/*/
/*#include <string.h>
* Replaced inline event and code definitions with an external header that
* has been automatically generated from the /usr/include/linux/input.h
* by the mkheader.pl utility
*/
#include "evtest.h"
#include <string.h>
#ifndef EV_SYN
#define EV_SYN 0
#endif
#include <string.h>

char **names[EV_MAX + 1] = {
[0 ... EV_MAX] = NULL,
[EV_SYN] = events, [EV_KEY] = keys,
[EV_REL] = relatives, [EV_ABS] = absolutes,
[EV_MSC] = misc, [EV_LED] = leds,
[EV_SND] = sounds, [EV_REP] = repeats,
[EV_FF] = forcefeedback, [EV_FF_STATUS] = ffstatus,
};

char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };

#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)

#define MYPORT 7046 // the port users will be connecting to
#define BACKLOG SOMAXCONN //10

//Struct for socket handler
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}

int main (int argc, char **argv) {

int fd, rd, i, j, k;
struct input_event ev[64];
int version;
unsigned short id[4];
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
char name[256] = "Unknown";
int abs[5];


// Network parameters
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char *messageCommand; // A message pointer will pointer the command string
messageCommand = (char *)malloc(5 + 1 + 5 + 1 + 5 + 1 + 2); //set the memory
//char *testMessage="Send the test string out!";


/* All about networking part
*
*/

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}

my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct


// What port am I on
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

/*
* In here, it starts to send the event to user
*/
if (argc < 2) {
printf("Usage: evtest /dev/input/eventX\n");
printf("Where X = input device number\n");
return 1;
}

if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
perror("evtest");
return 1;
}

if (ioctl(fd, EVIOCGVERSION, &version)) {
perror("evtest: can't get version");
return 1;
}

printf("Input driver version is %d.%d.%d\n",
version >> 16, (version >> 8) & 0xff, version & 0xff);

ioctl(fd, EVIOCGID, id);
printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

ioctl(fd, EVIOCGNAME(sizeof(name)), name);
printf("Input device name: \"%s\"\n", name);

memset(bit, 0, sizeof(bit));
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
printf("Supported events:\n");

for (i = 0; i < EV_MAX; i++) {
if (test_bit(i, bit[0])) {
printf(" Event type %d (%s)\n", i, events[i] ?events[i] : "?");
if (!i) continue;
ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
for (j = 0; j < KEY_MAX; j++) {
if (test_bit(j, bit[i])) {
printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
if (i == EV_ABS) {
ioctl(fd, EVIOCGABS(j), abs);
for (k = 0; k < 5; k++)
if ((k < 3) || abs[k])
printf(" %s %6d\n", absval[k], abs[k]);
}
}
}
}
}


#if 0
/*---Forever... ---*/
while (1)
{ int clientfd;
struct sockaddr_in client_addr;
socklen_t addrlen=sizeof(client_addr);

/*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

if (!fork())
{
/*---Echo back anything sent---*/
while (send(clientfd, /*buffer*/"t", 2, 0) != -1)
;
exit(0);
}

/*---Close data connection---*/
close(clientfd);
}

#endif


int connected;
printf("Wait for connection\n");
printf("Testing ... (interrupt to exit)\n");
while(1) // connection accept loop
{
//Setup a sending message destination, new_fd is the address where send to
sin_size = sizeof(struct sockaddr_in);
printf("waiting for connection...\n");
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);

printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));

pid_t pID = fork();
if (pID == 0)
{
printf("fork() child process\n");
// FORK START
close(sockfd); // sockfd is not needed in the child process

connected = 1;
while (connected) // data transfer loop
{
int sType=-1;
int sCode=-1;
int sValue=-1;

rd = read(fd, ev, sizeof(struct input_event) * 64);
if (rd < (int) sizeof(struct input_event))
{
printf("yyy\n");
perror("\nevtest: error reading");
return 1;
}

for (i = 0; i < rd / sizeof(struct input_event); i++)
{
printf("%d ", i);
if (ev[i].type == EV_SYN)
{
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
printf("Event: time %ld.%06ld, -------------- %s ------------\n",
ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
}
else
{
printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
ev[i].time.tv_sec, ev[i].time.tv_usec,
ev[i].type, events[ev[i].type] ? events[ev[i].type] : "?",
ev[i].code, names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
ev[i].value);
//Put into parameters
sType=ev[i].type;
sCode=ev[i].code;
sValue=ev[i].value;
sprintf(messageCommand, "%hd,%hd,%hd,\n", sType, sCode, sValue);

if (send(new_fd, messageCommand, strlen(messageCommand), 0) == -1)
{
printf("disconnected\n");
connected = 0;
break;
}
}// end else
} // end for loop
} //end while data transfer loop

close(new_fd);
// FORK END
exit(0);
} //end fork
else if (pID < 0)
printf("fork() failed\n");
else
{
printf("fork() parent process\n");
close(new_fd);
}

} //end while connection accept loop

close(sockfd);
// Free memory and close connection.
free(messageCommand);
close(sockfd);
}





/* End */
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
socket programming iiit Programming 2 07-05-2005 04:02 PM
Socket Programming jawadhashmi Programming 4 05-24-2005 03:04 AM
Socket programming maldini1010 Programming 4 02-11-2005 11:16 PM
socket programming???? harbir Linux - Networking 2 07-05-2004 02:52 AM
Socket Programming cxel91a Programming 4 03-19-2003 10:05 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:21 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration