Added multithread tcp client example.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11783 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
isiora 2018-03-16 18:31:51 +00:00
parent 259f9cace1
commit 70eecc1baf
4 changed files with 59 additions and 27 deletions

View File

@ -26,13 +26,13 @@
#define SERVER_PORT_NUM 8080 #define SERVER_PORT_NUM 8080
#define SERVER_IP_ADDRESS "192.168.1.76" #define SERVER_IP_ADDRESS "192.168.1.76"
void tcpexample(void) { void tcpexample(int port) {
int socket_fd; int socket_fd;
struct sockaddr_in ra; struct sockaddr_in ra;
int recv_data; char data_buffer[80]; int recv_data; char data_buffer[80];
struct fd_set rset; struct fd_set rset;
struct timeval tm = {5, 0}; struct timeval tm = {10, 0};
/* /*
* Creates an TCP socket, i.e. a SOCK_STREAM, with Internet Protocol Family, * Creates an TCP socket, i.e. a SOCK_STREAM, with Internet Protocol Family,
@ -42,7 +42,7 @@ void tcpexample(void) {
socket_fd = socket(PF_INET, SOCK_STREAM, 0); socket_fd = socket(PF_INET, SOCK_STREAM, 0);
if ( socket_fd < 0 ) { if ( socket_fd < 0 ) {
chprintf((BaseSequentialStream *)&SD1, "socket call failed"); chprintf((BaseSequentialStream *)&SD1, "socket call failed.\r\n");
return; return;
} }
@ -52,18 +52,20 @@ void tcpexample(void) {
memset(&ra, 0, sizeof(struct sockaddr_in)); memset(&ra, 0, sizeof(struct sockaddr_in));
ra.sin_family = AF_INET; ra.sin_family = AF_INET;
ra.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS); ra.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);
ra.sin_port = htons(SERVER_PORT_NUM); ra.sin_port = htons(port);
if (connect(socket_fd, (struct sockaddr *)&ra, if (connect(socket_fd, (struct sockaddr *)&ra,
sizeof (struct sockaddr_in)) < 0) { sizeof (struct sockaddr_in)) < 0) {
chprintf((BaseSequentialStream *)&SD1, "connect failed \n"); chprintf((BaseSequentialStream *)&SD1, "Connect failed.\r\n");
close(socket_fd); close(socket_fd);
return; return;
} }
if (send(socket_fd, "A' sfugliatella e o' babà.\r\n", while (true) {
sizeof "A' sfugliatella e o' babà.\r\n", 0) < 0) { chsnprintf(data_buffer, sizeof data_buffer,
chprintf((BaseSequentialStream *)&SD1, "send failed \n"); "Sending this message on port %d.\r\n", port);
if (send(socket_fd, data_buffer, strlen(data_buffer), 0) < 0) {
chprintf((BaseSequentialStream *)&SD1, "Send failed.\r\n");
close(socket_fd); close(socket_fd);
return; return;
} }
@ -71,22 +73,40 @@ void tcpexample(void) {
FD_SET(socket_fd, &rset); FD_SET(socket_fd, &rset);
recv_data = select(socket_fd+1, &rset, 0, 0, &tm); recv_data = select(socket_fd+1, &rset, 0, 0, &tm);
if (recv_data < 0) { if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "select failed \n"); chprintf((BaseSequentialStream *)&SD1, "Select failed.\r\n");
close(socket_fd); close(socket_fd);
return; return;
} }
} while (recv_data == 0); } while (recv_data == 0);
recv_data = recv(socket_fd, data_buffer, sizeof data_buffer, 0); recv_data = recv(socket_fd, data_buffer, sizeof data_buffer, 0);
if (recv_data < 0) { if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "recv failed \n"); chprintf((BaseSequentialStream *)&SD1, "Recv failed.\r\n");
close(socket_fd); close(socket_fd);
return; return;
} }
data_buffer[recv_data] = '\0'; data_buffer[recv_data] = '\0';
chprintf((BaseSequentialStream *)&SD1, "received data: %s\n",data_buffer); chprintf((BaseSequentialStream *)&SD1, "Received data: %s.\r\n", data_buffer);
}
close(socket_fd); close(socket_fd);
} }
/*
* Two threads that run the same tcp example on two
* different ports.
*/
static THD_WORKING_AREA(waThreadTcp1, 512);
static THD_WORKING_AREA(waThreadTcp2, 512);
static THD_FUNCTION(ThreadTcp, arg) {
int port = (int)arg;
tsWaitStubSkelReady();
chThdSleepMilliseconds(5000);
while (true) {
tcpexample(port);
chThdSleepMilliseconds(250);
}
}
/* /*
* LED blinker thread, times are in milliseconds. * LED blinker thread, times are in milliseconds.
*/ */
@ -109,8 +129,6 @@ static THD_FUNCTION(Thread1, arg) {
chThdSleepMilliseconds(160); chThdSleepMilliseconds(160);
palToggleLine(LINE_LED_BLUE); palToggleLine(LINE_LED_BLUE);
chThdSleepMilliseconds(600); chThdSleepMilliseconds(600);
tcpexample();
chThdSleepMilliseconds(5000);
} }
} }
@ -144,7 +162,9 @@ int main(void) {
/* /*
* Creates the blinker thread (and any other ancillary thread). * Creates the blinker thread (and any other ancillary thread).
*/ */
chThdCreateStatic(waThread1, sizeof waThread1, NORMALPRIO+10, Thread1, NULL); chThdCreateStatic(waThread1, sizeof waThread1, NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waThreadTcp1, sizeof waThreadTcp1, NORMALPRIO+10, ThreadTcp, (void *)8080);
chThdCreateStatic(waThreadTcp2, sizeof waThreadTcp2, NORMALPRIO+10, ThreadTcp, (void *)8081);
/* /*
* System initializations. * System initializations.

View File

@ -36,6 +36,7 @@
#define SKEL_REQ_GETOP 1 #define SKEL_REQ_GETOP 1
#define SKEL_REQ_CPYPRMS 2 #define SKEL_REQ_CPYPRMS 2
#define SKEL_REQ_PUTRES 3 #define SKEL_REQ_PUTRES 3
#define SKEL_REQ_READY 4
#define STUB_OP_SOCKET 0 #define STUB_OP_SOCKET 0
#define STUB_OP_CLOSE 1 #define STUB_OP_CLOSE 1

View File

@ -68,6 +68,7 @@ typedef struct stub_op {
static objects_fifo_t ops_fifo; static objects_fifo_t ops_fifo;
static msg_t ops_msgs[STUB_MAX_OPS]; static msg_t ops_msgs[STUB_MAX_OPS];
static struct stub_op ops[STUB_MAX_OPS] = {0}; static struct stub_op ops[STUB_MAX_OPS] = {0};
static bool tsSkelIsReady = false;
/*===========================================================================*/ /*===========================================================================*/
/* Module local functions. */ /* Module local functions. */
@ -149,6 +150,9 @@ THD_FUNCTION(TsStubsService, tsstate) {
} }
switch (skrp->req) { switch (skrp->req) {
case SKEL_REQ_READY:
tsSkelIsReady = true;
break;
case SKEL_REQ_GETOP: case SKEL_REQ_GETOP:
/* The nsec skeleton calls us to get a new op ready to be executed.*/ /* The nsec skeleton calls us to get a new op ready to be executed.*/
@ -245,6 +249,12 @@ THD_FUNCTION(TsStubsService, tsstate) {
} }
} }
void tsWaitStubSkelReady(void) {
while (!tsSkelIsReady) {
chThdSleepMilliseconds(100);
}
}
int socket(int domain, int type, int protocol) { int socket(int domain, int type, int protocol) {
stub_op_t *op = getNewOp(); stub_op_t *op = getNewOp();
op->op_code = STUB_OP_SOCKET; op->op_code = STUB_OP_SOCKET;

View File

@ -375,6 +375,7 @@ extern "C" {
int bind(int s, const struct sockaddr *name, socklen_t namelen); int bind(int s, const struct sockaddr *name, socklen_t namelen);
in_addr_t inet_addr(const char *cp); in_addr_t inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *addr); int inet_aton(const char *cp, struct in_addr *addr);
void tsWaitStubSkelReady(void);
THD_FUNCTION(TsStubsService, tsstate); THD_FUNCTION(TsStubsService, tsstate);
extern THD_WORKING_AREA(waTsStubsService, 1024); extern THD_WORKING_AREA(waTsStubsService, 1024);
#ifdef __cplusplus #ifdef __cplusplus