您的位置:首页 > 理论基础 > 计算机网络

Linux Socket 编程实例——TCP

2012-12-07 11:51 344 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: