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_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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue