Linux Socket 编程实例——TCP

Linux Socket编程实例(一个Hello World程序) 在Linux下写了个小的socket程序,分为客户端和服务器端,服务端开一个端口(2000),做为一个daemon,等待客户的连接请求.一旦有客 户连接,服务器端打印出客户端的IP地址和端口,并且向服务器端发送欢迎信息和时间.下面是服务端的代码(tcpserver.c).由于这只是个简单的 程序,所以只用了单线程实现!

单线程版本

服务端

/** 
* Tcp Server program, It is a simple example only. 
* zhengsh 200520602061 2 
* when client connect to server, send a welcome message and timestamp in server. 
*/  
#include <stdio.h>  
#include <sys/socket.h>  
#include <unistd.h>  
#include <sys/types.h>  
#include <netinet/in.h>  
#include <stdlib.h>  
#include <time.h>  
#include <string.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
  
  
#define SERVER_PORT 20000 // define the defualt connect port id  
#define LENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server  
#define BUFFER_SIZE 255  
#define WELCOME_MESSAGE "welcome to connect the server. "  
  
int main(int argc, char **argv)  
{  
    int i_servfd, i_clifd;  
    struct sockaddr_in servaddr,cliaddr;  
    if ( ( i_servfd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )  
    {  
        printf( "%s", "create socket error!\n" );  
        exit(1);  
    }  
    bzero( &servaddr, sizeof( servaddr ) );  
    servaddr.sin_family = AF_INET;  
    servaddr.sin_port = htons( SERVER_PORT );  
    servaddr.sin_addr.s_addr = htons( INADDR_ANY );  
    if ( bind( i_servfd,( struct sockaddr * )&servaddr, sizeof( servaddr ) ) < 0 )  
    {  
        printf( "bind to port %d failure!\n", SERVER_PORT );
        exit(1);  
    }  
    if ( listen( i_servfd, LENGTH_OF_LISTEN_QUEUE ) < 0 )  
    {  
        printf( "%s", "call listen failure!\n" );  
        exit(1);  
    }  
    while (1)  
    {  
        //server loop will nerver exit unless any body kill the process  
        char psz_buf[BUFFER_SIZE];  
        time_t time_curr;  
        socklen_t socklen_cliaddr = sizeof( cliaddr );  
        i_clifd = accept( i_servfd, ( struct sockaddr * )&cliaddr, &socklen_cliaddr );  
        if ( i_clifd < 0 )  
        {  
            printf( "%s", "error comes when call accept!\n" );  
            break;  
        }  
        strcpy( psz_buf, WELCOME_MESSAGE );  
        //inet_ntop(INET_ADDRSTRLEN,cliaddr.sin_addr,psz_buf,BUFFER_SIZE);  
  
        printf( "from client,IP:%s,Port:%d\n",  
            inet_ntoa(cliaddr.sin_addr), ntohs( cliaddr.sin_port ) );  
        time_curr = time(NULL);  
        strcat( psz_buf, "time_curr in server:" );  
        strcat( psz_buf, ctime( &time_curr ) );  
        send( i_clifd, psz_buf, BUFFER_SIZE, 0 );  
        close( i_clifd );  
    }//exit  
    close( i_servfd );  
    return 0;  
}  

客户端

客户每次用一个随机的端口连接服务器,并接收来自服务器的欢迎信息, 然后打印出来(tcpclient).运行的时候接受一个参数,也就是服务器的ip地址.

/* Tcp client program, It is a simple example only.
* zhengsh 200520602061 2
* connect to server, and echo a message from server.
*/

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define SERVER_PORT 20000 // define the defualt connect port id
#define CLIENT_PORT ( ( 20001 + rand() ) % 65536 ) // define the defualt client port as a random port
#define BUFFER_SIZE 255
#define REUQEST_MESSAGE "welcome to connect the server.\n"

void usage(char *name)
{
    printf( "usage: %s IpAddr\n",name);
}

int main(int argc, char **argv)
{ 
    int i_clifd, i_length = 0;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t socklen = sizeof(servaddr);
    char psz_buf[BUFFER_SIZE];

    if ( argc < 2 )
    {
        usage( argv[0] );
        exit(1);
    }

    if ( ( i_clifd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
    {
        printf( "create socket error!\n" );
        exit(1);
    }
    srand( time( NULL ) );//initialize random generator
    bzero( &cliaddr, sizeof( cliaddr ) );
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_port = htons( CLIENT_PORT );
    cliaddr.sin_addr.s_addr = htons( INADDR_ANY );
    bzero( &servaddr, sizeof( servaddr ) );
    servaddr.sin_family = AF_INET;
    inet_aton( argv[1], &servaddr.sin_addr );
    servaddr.sin_port = htons( SERVER_PORT );
    //servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    
    if ( bind( i_clifd, (struct sockaddr *)&cliaddr, sizeof( cliaddr ) ) < 0 )
    {
        printf( "bind to port %d failure!\n", CLIENT_PORT );
        exit(1);
    }
    if ( connect( i_clifd, (struct sockaddr *)&servaddr, socklen ) < 0 )
    {
        printf( "can't connect to %s!\n", argv[1] );
        exit(1);
    }

    i_length = recv( i_clifd, psz_buf, BUFFER_SIZE, 0 );
    if ( i_length < 0 )
    {
        printf( "error comes when recieve data from server %s!", argv[1] );
        exit(1);
    }
    printf( "from server %s :\n\t%s ", argv[1], psz_buf );
    close( i_clifd );
    return 0;
}

多线程版本:

server:

/** 
* Tcp Server program, It is a simple example only. 
* zhengsh 200520602061 2 
* when client connect to server, send a welcome message and timestamp in server. 
*/  
#include <stdio.h>  
#include <sys/socket.h>  
#include <unistd.h>  
#include <sys/types.h>  
#include <netinet/in.h>  
#include <stdlib.h>  
#include <time.h>  
#include <string.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>
#include <pthread.h>  
#include<errno.h>
  
#define SERVER_PORT 20000 // define the defualt connect port id  
#define LENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server  
#define BUFFER_SIZE 255  
#define WELCOME_MESSAGE "welcome to connect the server. "  

//extern int errno;

void *thread_func(void *ptr)  
{  
    int *pi_clifd = ptr;
    int i_length = 0;
    char psz_buf[BUFFER_SIZE] = {0};

    while(1)
    {
        memset( psz_buf, 0, sizeof( psz_buf ) );
        i_length = recv( *pi_clifd, psz_buf, BUFFER_SIZE, 0 );
        if ( i_length < 0 )  
        {  
            printf( "error comes when recieve data from peer!" );  
            close( *pi_clifd );
            return NULL;
        }  
        else if ( 0 == i_length )
        {
            printf( "peer has closed normally\n" );
            close( *pi_clifd );
            return NULL;
        }
        printf( "receive from client %d : %s\n", *pi_clifd, psz_buf );
    }
    return NULL;
}

  
int main(int argc, char **argv)  
{  
    int i_servfd, i_clifd;  
    pthread_t thrd;
    
    struct sockaddr_in servaddr,cliaddr;  
    if ( ( i_servfd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )  
    {  
        printf( "%s", "create socket error!\n" );  
        exit(1);  
    }  
    bzero( &servaddr, sizeof( servaddr ) );  
    servaddr.sin_family = AF_INET;  
    servaddr.sin_port = htons( SERVER_PORT );  
    servaddr.sin_addr.s_addr = htons( INADDR_ANY );  
    if ( bind( i_servfd,( struct sockaddr * )&servaddr, sizeof( servaddr ) ) < 0 )  
    {  
        printf( "bind to port %d failure!\n", SERVER_PORT );
        exit(1);  
    }  

    int i_reuseaddr = 1;
    setsockopt( i_servfd, SOL_SOCKET, SO_REUSEADDR, &i_reuseaddr, sizeof(i_reuseaddr) );

    if ( listen( i_servfd, LENGTH_OF_LISTEN_QUEUE ) < 0 )  
    {  
        printf( "%s", "call listen failure!\n" );  
        exit(1);  
    }  
    while (1)  
    {  
        //server loop will nerver exit unless any body kill the process  
        char psz_buf[BUFFER_SIZE];  
        time_t time_curr;  
        socklen_t socklen_cliaddr = sizeof( cliaddr );  
        i_clifd = accept( i_servfd, ( struct sockaddr * )&cliaddr, &socklen_cliaddr );  
        if ( i_clifd < 0 )  
        {  
            printf( "%s", "error comes when call accept!\n" );  
            break;  
        }
        
        strcpy( psz_buf, WELCOME_MESSAGE );  
        //inet_ntop(INET_ADDRSTRLEN,cliaddr.sin_addr,psz_buf,BUFFER_SIZE);  
  
        printf( "from client,IP:%s,Port:%d\n",  
            inet_ntoa(cliaddr.sin_addr), ntohs( cliaddr.sin_port ) );  
        time_curr = time(NULL);  
        strcat( psz_buf, "time_curr in server:" );  
        strcat( psz_buf, ctime( &time_curr ) );  
        send( i_clifd, psz_buf, BUFFER_SIZE, 0 );  

        pthread_create( &thrd, NULL, thread_func, (void *)&i_clifd );
         
    }//exit  
    close( i_servfd );  
    return 0;  
}  



client:

/* Tcp client program, It is a simple example only.
* zhengsh 200520602061 2
* connect to server, and echo a message from server.
*/

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define SERVER_PORT 20000 // define the defualt connect port id
#define CLIENT_PORT ( ( 20001 + rand() ) % 65536 ) // define the defualt client port as a random port
#define BUFFER_SIZE 255
#define REUQEST_MESSAGE "welcome to connect the server.\n"

void usage(char *name)
{
    printf( "usage: %s IpAddr\n",name);
}

int main(int argc, char **argv)
{ 
    int i_clifd, i_length = 0;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t socklen = sizeof(servaddr);
    char psz_buf[BUFFER_SIZE];

    if ( argc < 2 )
    {
        usage( argv[0] );
        exit(1);
    }

    if ( ( i_clifd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
    {
        printf( "create socket error!\n" );
        exit(1);
    }
    srand( time( NULL ) );//initialize random generator
    bzero( &cliaddr, sizeof( cliaddr ) );
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_port = htons( CLIENT_PORT );
    cliaddr.sin_addr.s_addr = htons( INADDR_ANY );
    bzero( &servaddr, sizeof( servaddr ) );
    servaddr.sin_family = AF_INET;
    inet_aton( argv[1], &servaddr.sin_addr );
    servaddr.sin_port = htons( SERVER_PORT );
    //servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    
    if ( bind( i_clifd, (struct sockaddr *)&cliaddr, sizeof( cliaddr ) ) < 0 )
    {
        printf( "bind to port %d failure!\n", CLIENT_PORT );
        exit(1);
    }
    if ( connect( i_clifd, (struct sockaddr *)&servaddr, socklen ) < 0 )
    {
        printf( "can't connect to %s!\n", argv[1] );
        exit(1);
    }

    i_length = recv( i_clifd, psz_buf, BUFFER_SIZE, 0 );
    if ( i_length < 0 )
    {
        printf( "error comes when recieve data from server %s!", argv[1] );
        exit(1);
    }
    printf( "from server %s :\n\t%s ", argv[1], psz_buf );

    while(1)
    {
        memset( psz_buf, 0, sizeof( psz_buf ) );
        scanf( "%s", psz_buf );
        send( i_clifd, psz_buf, strlen( psz_buf ), 0 );
    }
    //close( i_clifd );
    return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值