e1337coderz
asked on
Threaded Client Example
2 questions:
1) Could someone write a quick threaded client socket example for me? Basically I want this to be able to run on my RH9 box and i just need a little simple template that creates a thread that creates a socket and connects to yahoo.com:80 for example.This thread that creates a socket should do the following: Send "hello" Receive some data (store it in a chr*) and then send out the data it stored once it gets a "hello"from the server...
2) I need this thread to call a metheod (void) when something special happens (i.e. Server sends "bye")
Thanks
1) Could someone write a quick threaded client socket example for me? Basically I want this to be able to run on my RH9 box and i just need a little simple template that creates a thread that creates a socket and connects to yahoo.com:80 for example.This thread that creates a socket should do the following: Send "hello" Receive some data (store it in a chr*) and then send out the data it stored once it gets a "hello"from the server...
2) I need this thread to call a metheod (void) when something special happens (i.e. Server sends "bye")
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You could take a look at the following links:
http://www.cs.wustl.edu/~schmidt/ACE.html
http://www.developerweb.net/sock-faq/
http://sourceforge.net/projects/libsocks/
http://www.cs.wustl.edu/~schmidt/ACE.html
http://www.developerweb.net/sock-faq/
http://sourceforge.net/projects/libsocks/
pushed submit by mistake
HOW TO USE SOCKETS, example
-------------------------- ---------- ---------- --
For normal socket programs you need two communicating sides, one client one server. The server will be listening on some specific port for incoming connection and when it senses this connection it will spawn a connection with the client, i.e the listener will keep on listening for other connections still, but the already established connection will continue too...
(The best place to get info on sockets, UNIX network programming, by Richard Stevens)
Online stuff: This will get you started fast
http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/textcode.html)
A simple example that shows you this process ... A socket listens on say port 1234 for incoming connection, when it gets one, it will print "connection established" to the screen and it will then echo back whatever the client is writing to it ....
I have to admit I stole most of the code from stevens book. Afetr you compile the programs (Simply gcc client.c -o client and gcc server.c -o server), you run the server as
server
in one terminal
And then you can start client programs like
client youripaddress
then type a line of text enter
You will see the text displayed both at the server and the client
you can open other clients at the same time and run all of them at the same time
Now that you have a socket program that works and a thread program that work. next step is to spawn a thread instead of a process. In the server code, I used fork for each incoming connection. Now you have to change it in such a way that a new thread is started. And in that thread's main function, you implement the protocol you want.
Give it a try and we will be glad to answer any questions .
/*Client code */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#define MAXLINE 100
#define LISTENQ 10
#define SERV_PORT 1300
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt = 0;
static char *read_ptr;
static char read_buf[MAXLINE];
if (read_cnt <= 0)
{
again:
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return(-1);
} else if (read_cnt == 0)
return(0);
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return(1);
}
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
int n, rc;
char c, *ptr;
ptr = (char *) vptr;
for (n = 1; n < maxlen; n++)
{
if ( (rc = my_read(fd, &c)) == 1)
{
*ptr++ = c;
if (c == '\n')
break; /* newline is stored, like fgets() */
} else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return(-1); /* error, errno set by read() */
}
*ptr = 0; /* null terminate like fgets() */
return(n);
}
/* end readline */
ssize_t Readline(int fd, void *ptr, size_t maxlen)
{
ssize_t n;
if ( (n = readline(fd, ptr, maxlen)) < 0)
{
fprintf(stderr,"readline error");
exit(-14);
}
return(n);
}
ssize_t writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (const char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
/* end writen */
void Writen(int fd, void *ptr, size_t nbytes)
{
if (writen(fd, ptr, nbytes) != nbytes)
{
fprintf(stderr,"writen error");
exit(-14);
}
}
/* Read "n" bytes from a descriptor. */
ssize_t readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = (char*) vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */
ssize_t Readn(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ( (n = readn(fd, ptr, nbytes)) < 0)
{
fprintf(stderr,"readn error");
exit(-12);
}
return(n);
}
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
while(fgets(sendline, MAXLINE, fp) != NULL)
{
Writen(sockfd, sendline, strlen(sendline));
//read the echo of the command execution
if (Readline(sockfd, recvline, MAXLINE) == 0)
{
fprintf(stderr,"str_cli: server terminated prematurely");
exit(-12);
}
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
{
fprintf(stderr,"usage: tcpclient <IPaddress>");
exit(-12);
}
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error");
exit(-11);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
fprintf(stderr,"inet_pton error for %s", argv[1]);
exit(-12);
}
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
fprintf(stderr,"connection error");
exit(-13);
}
printf("Connection Established\n");
//shutdown(sockfd, SHUT_RDWR);
str_cli(stdin, sockfd);
}
/*server code*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <strings.h>
#define MAXLINE 100
#define LISTENQ 10
#define SERV_PORT 1300
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt = 0;
static char *read_ptr;
static char read_buf[MAXLINE];
if (read_cnt <= 0)
{
again:
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return(-1);
} else if (read_cnt == 0)
return(0);
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return(1);
}
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
int n, rc;
char c, *ptr;
ptr = (char *) vptr;
for (n = 1; n < maxlen; n++)
{
if ( (rc = my_read(fd, &c)) == 1)
{
*ptr++ = c;
if (c == '\n')
break; /* newline is stored, like fgets() */
} else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return(-1); /* error, errno set by read() */
}
*ptr = 0; /* null terminate like fgets() */
return(n);
}
/* end readline */
ssize_t Readline(int fd, void *ptr, size_t maxlen)
{
ssize_t n;
if ( (n = readline(fd, ptr, maxlen)) < 0)
{
fprintf(stderr,"readline error");
exit(-14);
}
return(n);
}
ssize_t writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (const char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
//cout << "chars written " << n << endl;
return(n);
}
/* end writen */
void Writen(int fd, void *ptr, size_t nbytes)
{
if (writen(fd, ptr, nbytes) != nbytes)
{
fprintf(stderr,"writen error");
exit(-14);
}
// cout << "written" << endl;
}
/* Read "n" bytes from a descriptor. */
ssize_t readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = (char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */
ssize_t Readn(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ( (n = readn(fd, ptr, nbytes)) < 0)
{
fprintf(stderr,"readn error");
exit(-12);
}
return(n);
}
void echo (int sockfd, int id)
{
ssize_t n;
char recvline[MAXLINE];
printf("Connection Established with client # %d\n", id);
for ( ; ; )
{
if ( (n=Readline(sockfd, recvline, MAXLINE)) == 0)
{
fprintf(stderr,"str_cli: server terminated prematurely");
exit(-12);
}
//wirte it here;
printf("From #%d\n", id);
fputs(recvline, stdout);
//write it back to the client
Writen(sockfd, recvline, strlen(recvline));
}
//close(sockfd);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
int clilen;
int id =0;
struct sockaddr_in servaddr, cliaddr;
if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error");
exit(-11);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr=h tonl(INADD R_ANY);
if ((bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
{
fprintf(stderr,"socket bind error");
exit(-12);
}
if ((listen(listenfd, LISTENQ)) < 0)
{
fprintf(stderr,"socket listen error");
exit(-13);
}
for ( ; ; )
{
clilen = sizeof(cliaddr);
if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0)
{
fprintf(stderr,"socket accept error");
exit(-14);
}
if ( (childpid = fork()) == 0)
{
id++;
close(listenfd);
echo(connfd,id);
exit(0);
}
close(connfd);
}
}
HOW TO USE SOCKETS, example
--------------------------
For normal socket programs you need two communicating sides, one client one server. The server will be listening on some specific port for incoming connection and when it senses this connection it will spawn a connection with the client, i.e the listener will keep on listening for other connections still, but the already established connection will continue too...
(The best place to get info on sockets, UNIX network programming, by Richard Stevens)
Online stuff: This will get you started fast
http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/textcode.html)
A simple example that shows you this process ... A socket listens on say port 1234 for incoming connection, when it gets one, it will print "connection established" to the screen and it will then echo back whatever the client is writing to it ....
I have to admit I stole most of the code from stevens book. Afetr you compile the programs (Simply gcc client.c -o client and gcc server.c -o server), you run the server as
server
in one terminal
And then you can start client programs like
client youripaddress
then type a line of text enter
You will see the text displayed both at the server and the client
you can open other clients at the same time and run all of them at the same time
Now that you have a socket program that works and a thread program that work. next step is to spawn a thread instead of a process. In the server code, I used fork for each incoming connection. Now you have to change it in such a way that a new thread is started. And in that thread's main function, you implement the protocol you want.
Give it a try and we will be glad to answer any questions .
/*Client code */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#define MAXLINE 100
#define LISTENQ 10
#define SERV_PORT 1300
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt = 0;
static char *read_ptr;
static char read_buf[MAXLINE];
if (read_cnt <= 0)
{
again:
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return(-1);
} else if (read_cnt == 0)
return(0);
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return(1);
}
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
int n, rc;
char c, *ptr;
ptr = (char *) vptr;
for (n = 1; n < maxlen; n++)
{
if ( (rc = my_read(fd, &c)) == 1)
{
*ptr++ = c;
if (c == '\n')
break; /* newline is stored, like fgets() */
} else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return(-1); /* error, errno set by read() */
}
*ptr = 0; /* null terminate like fgets() */
return(n);
}
/* end readline */
ssize_t Readline(int fd, void *ptr, size_t maxlen)
{
ssize_t n;
if ( (n = readline(fd, ptr, maxlen)) < 0)
{
fprintf(stderr,"readline error");
exit(-14);
}
return(n);
}
ssize_t writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (const char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
/* end writen */
void Writen(int fd, void *ptr, size_t nbytes)
{
if (writen(fd, ptr, nbytes) != nbytes)
{
fprintf(stderr,"writen error");
exit(-14);
}
}
/* Read "n" bytes from a descriptor. */
ssize_t readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = (char*) vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */
ssize_t Readn(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ( (n = readn(fd, ptr, nbytes)) < 0)
{
fprintf(stderr,"readn error");
exit(-12);
}
return(n);
}
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
while(fgets(sendline, MAXLINE, fp) != NULL)
{
Writen(sockfd, sendline, strlen(sendline));
//read the echo of the command execution
if (Readline(sockfd, recvline, MAXLINE) == 0)
{
fprintf(stderr,"str_cli: server terminated prematurely");
exit(-12);
}
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
{
fprintf(stderr,"usage: tcpclient <IPaddress>");
exit(-12);
}
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error");
exit(-11);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
fprintf(stderr,"inet_pton error for %s", argv[1]);
exit(-12);
}
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
fprintf(stderr,"connection
exit(-13);
}
printf("Connection Established\n");
//shutdown(sockfd, SHUT_RDWR);
str_cli(stdin, sockfd);
}
/*server code*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <strings.h>
#define MAXLINE 100
#define LISTENQ 10
#define SERV_PORT 1300
static ssize_t my_read(int fd, char *ptr)
{
static int read_cnt = 0;
static char *read_ptr;
static char read_buf[MAXLINE];
if (read_cnt <= 0)
{
again:
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return(-1);
} else if (read_cnt == 0)
return(0);
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return(1);
}
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
int n, rc;
char c, *ptr;
ptr = (char *) vptr;
for (n = 1; n < maxlen; n++)
{
if ( (rc = my_read(fd, &c)) == 1)
{
*ptr++ = c;
if (c == '\n')
break; /* newline is stored, like fgets() */
} else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return(-1); /* error, errno set by read() */
}
*ptr = 0; /* null terminate like fgets() */
return(n);
}
/* end readline */
ssize_t Readline(int fd, void *ptr, size_t maxlen)
{
ssize_t n;
if ( (n = readline(fd, ptr, maxlen)) < 0)
{
fprintf(stderr,"readline error");
exit(-14);
}
return(n);
}
ssize_t writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (const char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
//cout << "chars written " << n << endl;
return(n);
}
/* end writen */
void Writen(int fd, void *ptr, size_t nbytes)
{
if (writen(fd, ptr, nbytes) != nbytes)
{
fprintf(stderr,"writen error");
exit(-14);
}
// cout << "written" << endl;
}
/* Read "n" bytes from a descriptor. */
ssize_t readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = (char*)vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */
ssize_t Readn(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ( (n = readn(fd, ptr, nbytes)) < 0)
{
fprintf(stderr,"readn error");
exit(-12);
}
return(n);
}
void echo (int sockfd, int id)
{
ssize_t n;
char recvline[MAXLINE];
printf("Connection Established with client # %d\n", id);
for ( ; ; )
{
if ( (n=Readline(sockfd, recvline, MAXLINE)) == 0)
{
fprintf(stderr,"str_cli: server terminated prematurely");
exit(-12);
}
//wirte it here;
printf("From #%d\n", id);
fputs(recvline, stdout);
//write it back to the client
Writen(sockfd, recvline, strlen(recvline));
}
//close(sockfd);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
int clilen;
int id =0;
struct sockaddr_in servaddr, cliaddr;
if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error");
exit(-11);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr=h
if ((bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
{
fprintf(stderr,"socket bind error");
exit(-12);
}
if ((listen(listenfd, LISTENQ)) < 0)
{
fprintf(stderr,"socket listen error");
exit(-13);
}
for ( ; ; )
{
clilen = sizeof(cliaddr);
if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0)
{
fprintf(stderr,"socket accept error");
exit(-14);
}
if ( (childpid = fork()) == 0)
{
id++;
close(listenfd);
echo(connfd,id);
exit(0);
}
close(connfd);
}
}
ASKER