入门多线程服务器程序实例

fedora core 5
g++

服务器端程序:

#include  < stdlib.h >

#include 
< sys / types.h >

#include 
< sys / socket.h >

#include 
< netinet / in .h >

#include 
< unistd.h >

#include 
< pthread.h >

#include 
< stdio.h >

#include 
< string .h >

#include 
< arpa / inet.h >



#define  PORT 8848

#define  BACKLOG 5

#define  MAXDATASIZE 1000



void  process_cli( int  connectfd, sockaddr_in client);



void *  start_routine( void *  arg);

struct  ARG {

       
int  connfd;

       sockaddr_in client;

       };

       

main()

{

      
int  listenfd, connectfd;

      pthread_t thread;         
// id of thread

      ARG 
* arg;

      
struct  sockaddr_in server;  // server's address info

      
struct  sockaddr_in client;  // client's

      
int  sin_size;

      

      
// create tcp socket

      printf(
" socket.... " );

      
if  ((listenfd  =  socket(AF_INET, SOCK_STREAM,  0 ))  ==   - 1 ) {

                    perror(
" creating socket failed. " );

                    exit(
1 );

      }

      

      
int  opt  =  SO_REUSEADDR;

      setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, 
& opt,  sizeof (opt));

      

      bzero(
& server, sizeof (server));

      server.sin_family 
=  AF_INET;

      server.sin_port 
=  htons(PORT);

      server.sin_addr.s_addr 
=  htonl(INADDR_ANY);

      printf(
" bind.... " );

      
if (bind(listenfd,( struct  sockaddr  * ) & server, sizeof ( struct  sockaddr))  ==   - 1 ) {

          perror(
" bind error. " );

          exit(
1 );

      }

      

      printf(
" listen.... " );

      
if (listen(listenfd,BACKLOG)  ==   - 1 ) {

          perror(
" listen() error " );

          exit(
1 );

      }



      sin_size 
=   sizeof ( struct  sockaddr_in);

      
while ( 1 )

      {

          
// accept() using main thread

          printf(
" accepting.... " );

          
if ((connectfd  =  accept(listenfd,

                     (
struct  sockaddr  * ) & client,

                     (socklen_t
* ) & sin_size))  ==   - 1 ) {

              perror(
" accept() error " );

              exit(
1 );

          }



          arg 
=   new  ARG;

          arg
-> connfd  =  connectfd;

          memcpy((
void   * ) & arg -> client,  & client,  sizeof (client));

        

          
// invoke start_routine to handle this thread

          printf(
" thread_creating.... " );

          
if (pthread_create( & thread, NULL, start_routine, ( void * )arg)){

              perror(
" pthread_creat() error " );

              exit(
1 );

          }          

      }

      close(listenfd);      

}



void  process_cli( int  connectfd, sockaddr_in client)

{

    
int  num;

    
char  recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];

    

    printf(
" you got a connection from %s.   " ,inet_ntoa(client.sin_addr) );

    
// get client's name from client

    num 
=  recv(connectfd, cli_name, MAXDATASIZE,  0 );

    
if (num  ==   0 ) {

        close(connectfd);

        printf(
" Client disconnected. " );

        
return ;

    }

    cli_name[num 
-   1 =   '

 客户端代码:

/*  cthread.c  */
#include 
< stdio.h >
#include 
< sys / types.h >
#include 
< netinet / in .h >
#include 
< sys / socket.h >
#include 
< netdb.h >
#include 
< unistd.h >
#include 
< string .h >
#include 
< arpa / inet.h >
#include 
< errno.h >
#include 
< stdlib.h >
#define  PORT 8848
#define  MAXDATASIZE 100

void  process(FILE  * fp,  int  sockfd);
char *  getMessage( char *  sendline,  int  len, FILE *  fp);
int  main( int  argc,  char   * argv[])
{
    
int  fd;
    
struct  hostent  * he;
    
struct  sockaddr_in server;  // server's address info

    
if (argc  !=   2 ) {
        printf(
" Usage: %s <ip address> " ,argv[ 0 ]);
        exit(
1 );
    }
    
    
if ((he  =  gethostbyname(argv[ 1 ]))  ==  NULL){
        perror(
" gethostbyname() error " );
        exit(
1 );
    }

    
if ((fd  =  socket(AF_INET, SOCK_STREAM,  0 ))  ==   - 1 ){
        perror(
" socket() error " );
        exit(
1 );
    }

    bzero(
& server ,  sizeof (server));
    server.sin_family 
=  AF_INET;
    server.sin_port 
=  htons(PORT);
    server.sin_addr 
=   * (( struct  in_addr  * )he -> h_addr);

    
if (connect(fd, ( struct  sockaddr  * ) & server,
                
sizeof ( struct  sockaddr))  ==   - 1 ){
        perror(
" connect() error " );
        exit(
1 );
    }

    process(stdin,fd);

    close(fd);
}

void  process(FILE  * fp,  int  sockfd)
{
    
char  sendline[MAXDATASIZE],recvline[MAXDATASIZE];
    
int  numbytes;

    printf(
" connected to server. " );
    
// send name to server
    printf( " Input name: " );
    
if (fgets(sendline, MAXDATASIZE, fp)  ==  NULL){
        printf(
" Exit. " );
        
return ;
    }
    send(sockfd, sendline, strlen(sendline), 
0 );

    
// send message to server
    
// when the string is not NULL , send another!
     while (getMessage(sendline,MAXDATASIZE,fp)  !=  NULL) {
        send(sockfd, sendline, strlen(sendline), 
0 );

        
if ((numbytes  =  recv(sockfd, recvline, MAXDATASIZE,  0 ))  ==   0 ){
            printf(
" server terminated. " );
            
return ;
        }
        recvline[numbytes] 
=   '

编译命令:

g++ -g -o s sthread.c -pthread

g++ -g -o c cthread.c -lc -lnsl

启动服务器:

./s

启动客户端:

./c 127.0.0.1

然后提示输入客户机的名字,再就提示输入一串字符,然后服务器就反转再发回来。

你可能感兴趣的:(多线程,socket,struct,server,服务器,FP)