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:
parent
259f9cace1
commit
70eecc1baf
|
@ -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,41 +52,61 @@ 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);
|
||||||
close(socket_fd);
|
if (send(socket_fd, data_buffer, strlen(data_buffer), 0) < 0) {
|
||||||
return;
|
chprintf((BaseSequentialStream *)&SD1, "Send failed.\r\n");
|
||||||
}
|
|
||||||
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");
|
|
||||||
close(socket_fd);
|
close(socket_fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (recv_data == 0);
|
do {
|
||||||
recv_data = recv(socket_fd, data_buffer, sizeof data_buffer, 0);
|
FD_SET(socket_fd, &rset);
|
||||||
if (recv_data < 0) {
|
recv_data = select(socket_fd+1, &rset, 0, 0, &tm);
|
||||||
chprintf((BaseSequentialStream *)&SD1, "recv failed \n");
|
if (recv_data < 0) {
|
||||||
close(socket_fd);
|
chprintf((BaseSequentialStream *)&SD1, "Select failed.\r\n");
|
||||||
return;
|
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);
|
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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue