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_IP_ADDRESS "192.168.1.76"
void tcpexample(void) {
void tcpexample(int port) {
int socket_fd;
struct sockaddr_in ra;
int recv_data; char data_buffer[80];
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,
@ -42,7 +42,7 @@ void tcpexample(void) {
socket_fd = socket(PF_INET, SOCK_STREAM, 0);
if ( socket_fd < 0 ) {
chprintf((BaseSequentialStream *)&SD1, "socket call failed");
chprintf((BaseSequentialStream *)&SD1, "socket call failed.\r\n");
return;
}
@ -52,41 +52,61 @@ void tcpexample(void) {
memset(&ra, 0, sizeof(struct sockaddr_in));
ra.sin_family = AF_INET;
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,
sizeof (struct sockaddr_in)) < 0) {
chprintf((BaseSequentialStream *)&SD1, "connect failed \n");
chprintf((BaseSequentialStream *)&SD1, "Connect failed.\r\n");
close(socket_fd);
return;
}
if (send(socket_fd, "A' sfugliatella e o' babà.\r\n",
sizeof "A' sfugliatella e o' babà.\r\n", 0) < 0) {
chprintf((BaseSequentialStream *)&SD1, "send failed \n");
close(socket_fd);
return;
}
do {
FD_SET(socket_fd, &rset);
recv_data = select(socket_fd+1, &rset, 0, 0, &tm);
if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "select failed \n");
while (true) {
chsnprintf(data_buffer, sizeof data_buffer,
"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);
return;
}
} while (recv_data == 0);
recv_data = recv(socket_fd, data_buffer, sizeof data_buffer, 0);
if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "recv failed \n");
close(socket_fd);
return;
do {
FD_SET(socket_fd, &rset);
recv_data = select(socket_fd+1, &rset, 0, 0, &tm);
if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "Select failed.\r\n");
close(socket_fd);
return;
}
} while (recv_data == 0);
recv_data = recv(socket_fd, data_buffer, sizeof data_buffer, 0);
if (recv_data < 0) {
chprintf((BaseSequentialStream *)&SD1, "Recv failed.\r\n");
close(socket_fd);
return;
}
data_buffer[recv_data] = '\0';
chprintf((BaseSequentialStream *)&SD1, "Received data: %s.\r\n", data_buffer);
}
data_buffer[recv_data] = '\0';
chprintf((BaseSequentialStream *)&SD1, "received data: %s\n",data_buffer);
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.
*/
@ -109,8 +129,6 @@ static THD_FUNCTION(Thread1, arg) {
chThdSleepMilliseconds(160);
palToggleLine(LINE_LED_BLUE);
chThdSleepMilliseconds(600);
tcpexample();
chThdSleepMilliseconds(5000);
}
}
@ -144,7 +162,9 @@ int main(void) {
/*
* 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.

View File

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

View File

@ -68,6 +68,7 @@ typedef struct stub_op {
static objects_fifo_t ops_fifo;
static msg_t ops_msgs[STUB_MAX_OPS];
static struct stub_op ops[STUB_MAX_OPS] = {0};
static bool tsSkelIsReady = false;
/*===========================================================================*/
/* Module local functions. */
@ -149,6 +150,9 @@ THD_FUNCTION(TsStubsService, tsstate) {
}
switch (skrp->req) {
case SKEL_REQ_READY:
tsSkelIsReady = true;
break;
case SKEL_REQ_GETOP:
/* 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) {
stub_op_t *op = getNewOp();
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);
in_addr_t inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *addr);
void tsWaitStubSkelReady(void);
THD_FUNCTION(TsStubsService, tsstate);
extern THD_WORKING_AREA(waTsStubsService, 1024);
#ifdef __cplusplus