在学习了Client 端常用的 socket , connect 和 Server 端常用的 socket bind listen accept
之后,打算写一个Client 端向 Server 发送连接请求的完整程序。
收发消息的 client/server 端可以分为阻塞方式和非阻塞方式,
这两种方式下,为了使得运行结果清晰可见,我们在这里做这样的约定
1.如果 server 端接收消息的方式是阻塞的话,那么首先启动 server端的程序代码,
待到 server 端因为没有接到任何的来自于 client 的请求信息而执行 accept 方法时处于等待状态。
此时再来启动 client 端的代码
2. 如果 server 端接收消息的方式是非阻塞的话,那么在 client 端中以 connect 方法为循环变量,
直到 connect 发送的连接请求得到 server端的回复信息之后,才会是循环结束,否则一直执行循环,
不断的向 server 端发送请求连接的消息。
示例代码1 : 阻塞方式
编译代码命令
g++ clientTest.cpp -o client
g++ serverTest.cpp -o server
// client 端代码
-
// clientTest.cpp
-
-
#include <stdio.h> // perror
-
#include <string.h> // memset
-
-
#include <sys/types.h> // AF_INET
-
#include <sys/socket.h> // socket
-
#include <netinet/in.h> // sockaddr_in
-
#include <arpa/inet.h> // inet_aton
-
#include <unistd.h> // unix standard library
-
-
-
#define SERVER_PORT 3699
-
-
#define SERVER_IP "10.0.2.15"
-
-
-
int getSocketDone ()
-
{
-
int ret = socket(AF_INET, SOCK_STREAM , 0) ;
-
if ( ret < 0 )
-
perror ("getSocketDone failed") ;
-
return ret ;
-
}
-
-
int getConnectDone ( int sock_fd )
-
{
-
int ret ;
-
struct sockaddr_in serv_addr ;
-
memset ( &serv_addr , 0 , sizeof( struct sockaddr_in ) ) ;
-
-
serv_addr.sin_family = AF_INET ;
-
serv_addr.sin_port = htons(SERVER_PORT) ;
-
-
ret = inet_aton (SERVER_IP , &serv_addr.sin_addr) ;
-
if ( ret < 0 )
-
{
-
perror ("inet_aton failed ") ;
-
return ret ;
-
}
-
-
ret = connect (sock_fd , (struct sockaddr *)(&serv_addr) , sizeof( struct sockaddr_in )) ;
-
-
if ( ret < 0 )
-
perror ("getConnectDone failed ") ;
-
-
return ret ;
-
}
-
-
-
int main ( int c , char ** v )
-
{
-
int sock_fd , ret ;
-
-
sock_fd = getSocketDone () ;
-
-
if (sock_fd > 0 )
-
printf(" client getSocketDone success sock_fd = %d \n" , sock_fd);
-
else
-
goto error ;
-
-
if ( !getConnectDone ( sock_fd ) )
-
{
-
printf (" client getConnectDone success \n") ;
-
goto success ;
-
}
-
else
-
goto error ;
-
-
error :
-
perror ("failed ") ;
-
goto success ;
-
success :
-
return 0 ;
-
}
// server 端代码
-
//serverTest.cpp
-
-
#include <stdio.h>
-
-
#include <string.h> // memset
-
-
#include <sys/types.h> // AF_INET , AF_INET6 , SOCK_STREAM , SOCK_DGRAM
-
-
#include <sys/socket.h> // socket , bind , listen , accept
-
-
#include <netinet/in.h> // sockaddr_in
-
-
#include <unistd.h> // unix standard library
-
-
#include <fcntl.h> // fcntl , set accept non-block mode
-
-
-
#define SERVER_PORT 3699
-
-
#define MAX_LISTEN_QUEUE_LENGTH 10
-
-
-
int getSocketDone ()
-
-
{
-
-
int ret = socket (AF_INET, SOCK_STREAM , 0 ) ;
-
-
if ( ret < 0 )
-
-
perror ("getSocketDone failed") ;
-
-
-
-
return ret ;
-
-
}
-
-
-
int getBindDone ( int sock_fd )
-
-
{
-
-
struct sockaddr_in serv_addr ;
-
-
int ret ;
-
-
-
memset ( &serv_addr , 0 , sizeof( struct sockaddr_in )) ;
-
-
serv_addr.sin_family = AF_INET ;
-
-
serv_addr.sin_port = htons (SERVER_PORT) ;
-
-
serv_addr.sin_addr.s_addr = htonl ( INADDR_ANY ) ;
-
-
-
-
ret = bind (sock_fd , (struct sockaddr *)(&serv_addr) , sizeof( struct sockaddr_in ) ) ;
-
-
-
if ( ret < 0 )
-
-
perror ("getBindDone failed");
-
-
return ret ;
-
-
}
-
-
-
int getListenDone ( int sock_fd )
-
-
{
-
-
int ret = listen ( sock_fd , MAX_LISTEN_QUEUE_LENGTH ) ;
-
-
if ( ret < 0 )
-
-
perror ("getListenDone failed ") ;
-
-
return ret ;
-
-
}
-
-
-
int setNonBlock ( int *sock_fd )
-
-
{
-
-
int ret = fcntl (*sock_fd , F_SETFL , O_NONBLOCK) ;
-
-
if ( ret < 0 )
-
-
perror ("setNonBlock failed") ;
-
-
return ret ;
-
-
}
-
-
-
int getAcceptDone ( int sock_fd_queue , struct sockaddr_in *client_addr , int *client_len )
-
-
{
-
-
int sock_fd_conn ;
-
-
*client_len = sizeof( struct sockaddr_in) ;
-
-
sock_fd_conn = accept (sock_fd_queue , (struct sockaddr *)client_addr ,(socklen_t*) client_len) ;
-
-
if ( sock_fd_conn < 0 )
-
-
perror ("getAcceptDone failed ") ;
-
-
return sock_fd_conn ;
-
-
}
-
-
// this is the blocking mode ,first get server start
-
-
// then execute the client
-
-
-
int main ( int c , char ** v )
-
-
{
-
-
int sock_fd_queue, sock_fd_conn , ret ;
-
-
int client_len ;
-
-
struct sockaddr_in client_addr ;
-
-
sock_fd_queue = getSocketDone () ;
-
-
if ( sock_fd_queue > 0 )
-
-
printf ("getSocketDone success \n") ;
-
-
else
-
-
goto error ;
-
-
-
if ( !getBindDone ( sock_fd_queue ) )
-
-
printf ("getBindDone success \n") ;
-
-
else
-
-
goto error ;
-
-
if ( !getListenDone ( sock_fd_queue ))
-
-
printf ("getListenDone success \n") ;
-
-
else
-
-
goto error ;
-
-
-
if ( ( sock_fd_conn = getAcceptDone (sock_fd_queue , &(client_addr) , &(client_len) ) ) > 0 )
-
-
{
-
-
printf ("getAcceptDone success , new socket connect fd is %d\n" , sock_fd_conn ) ;
-
-
printf ("peer port : %s" , ntohs(client_addr.sin_port)) ;
-
-
goto success ;
-
-
}
-
-
else
-
-
goto error ;
-
-
error :
-
-
perror ("method failed") ;
-
-
goto success ;
-
-
success :
-
-
return 0 ;
-
-
}
代码运行结果
首先运行 server , 然后打开一个新的命令终端窗口运行 client
./server 控制台打印信息
etSocketDone success
getBindDone success
getListenDone success
getAcceptDone success , new socket connect fd is 4
Segmentation fault (core dumped)
./client 显示信息如下
client getSocketDone success sock_fd = 3
client getConnectDone success
示例代码2 : server 端以阻塞的方式来接收来自 client 端的消息
大部分代码和示例代码1 相同,红色代码除外
// Client 端代码 (首先运行 client 端代码)
-
// clientTest2.cpp
-
// non-blocking working mode
-
-
#include <stdio.h> // perror
-
#include <string.h> // memset
-
-
#include <sys/types.h> // AF_INET
-
#include <sys/socket.h> // socket
-
#include <netinet/in.h> // sockaddr_in
-
#include <arpa/inet.h> // inet_aton
-
#include <unistd.h> // unix standard library
-
-
-
#define SERVER_PORT 3699
-
-
#define SERVER_IP "10.0.2.15"
-
-
-
int getSocketDone ()
-
{
-
int ret = socket(AF_INET, SOCK_STREAM , 0) ;
-
if ( ret < 0 )
-
perror ("getSocketDone failed") ;
-
return ret ;
-
}
-
-
int getConnectDone ( int sock_fd )
-
{
-
int ret ;
-
struct sockaddr_in serv_addr ;
-
memset ( &serv_addr , 0 , sizeof( struct sockaddr_in ) ) ;
-
-
serv_addr.sin_family = AF_INET ;
-
serv_addr.sin_port = htons(SERVER_PORT) ;
-
-
ret = inet_aton (SERVER_IP , &serv_addr.sin_addr) ;
-
if ( ret < 0 )
-
{
-
perror ("inet_aton failed ") ;
-
return ret ;
-
}
-
-
ret = connect (sock_fd , (struct sockaddr *)(&serv_addr) , sizeof( struct sockaddr_in )) ;
-
-
if ( ret < 0 )
-
perror ("getConnectDone failed ") ;
-
-
return ret ;
-
}
-
-
-
int main ( int c , char ** v )
-
{
-
int sock_fd , ret ;
-
-
sock_fd = getSocketDone () ;
-
-
if (sock_fd > 0 )
-
printf(" client getSocketDone success sock_fd = %d \n" , sock_fd);
-
else
-
goto error ;
-
-
while ( getConnectDone ( sock_fd ) < 0 )
-
{
-
printf ("waiting for server set up\n ") ;
-
}
-
-
printf ("success send connect request to server \n") ;
-
goto success ;
-
-
error :
-
perror ("failed ") ;
-
goto success ;
-
success :
-
return 0 ;
-
}
// Server 端代码 (然后打开一个空闲的命令终端,运行 Server 端代码)
-
//serverTest2.cpp
-
// non-block
-
-
#include <stdio.h>
-
#include <string.h> // memset
-
-
#include <sys/types.h> // AF_INET , AF_INET6 , SOCK_STREAM , SOCK_DGRAM
-
#include <sys/socket.h> // socket , bind , listen , accept
-
#include <netinet/in.h> // sockaddr_in
-
#include <unistd.h> // unix standard library
-
#include <fcntl.h> // fcntl , set accept non-block mode
-
-
-
#define SERVER_PORT 3699
-
#define MAX_LISTEN_QUEUE_LENGTH 10
-
-
-
int getSocketDone ()
-
{
-
int ret = socket (AF_INET, SOCK_STREAM , 0 ) ;
-
if ( ret < 0 )
-
perror ("getSocketDone failed") ;
-
-
return ret ;
-
}
-
-
int getBindDone ( int sock_fd )
-
{
-
struct sockaddr_in serv_addr ;
-
int ret ;
-
-
memset ( &serv_addr , 0 , sizeof( struct sockaddr_in )) ;
-
serv_addr.sin_family = AF_INET ;
-
serv_addr.sin_port = htons (SERVER_PORT) ;
-
serv_addr.sin_addr.s_addr = htonl ( INADDR_ANY ) ;
-
-
ret = bind (sock_fd , (struct sockaddr *)(&serv_addr) , sizeof( struct sockaddr_in ) ) ;
-
-
if ( ret < 0 )
-
perror ("getBindDone failed");
-
-
return ret ;
-
}
-
-
int getListenDone ( int sock_fd )
-
{
-
int ret = listen ( sock_fd , MAX_LISTEN_QUEUE_LENGTH ) ;
-
-
if ( ret < 0 )
-
perror ("getListenDone failed ") ;
-
-
return ret ;
-
}
-
-
int setNonBlock ( int *sock_fd )
-
{
-
int ret = fcntl (*sock_fd , F_SETFL , O_NONBLOCK) ;
-
if ( ret < 0 )
-
perror ("setNonBlock failed") ;
-
-
return ret ;
-
}
-
-
int getAcceptDone ( int sock_fd_queue , struct sockaddr_in *client_addr , int *client_len )
-
{
-
int sock_fd_conn ;
-
-
*client_len = sizeof( struct sockaddr_in) ;
-
-
sock_fd_conn = accept (sock_fd_queue , (struct sockaddr *)client_addr ,(socklen_t*) client_len) ;
-
-
if ( sock_fd_conn < 0 )
-
perror ("getAcceptDone failed ") ;
-
return sock_fd_conn ;
-
}
-
-
// this is the blocking mode ,first get server start
-
// then execute the client
-
-
int main ( int c , char ** v )
-
{
-
int sock_fd_queue, sock_fd_conn , ret ;
-
int client_len ;
-
struct sockaddr_in client_addr ;
-
-
-
sock_fd_queue = getSocketDone () ;
-
-
if ( sock_fd_queue > 0 )
-
printf ("getSocketDone success \n") ;
-
else
-
goto error ;
-
-
if ( !getBindDone ( sock_fd_queue ) )
-
printf ("getBindDone success \n") ;
-
else
-
goto error ;
-
-
if ( !getListenDone ( sock_fd_queue ))
-
printf ("getListenDone success \n") ;
-
else
-
goto error ;
-
-
// set non block mode
-
if ( !setNonBlock (&sock_fd_queue) )
-
printf ("set server accepting mode non-blocking \n") ;
-
else
-
goto error ;
-
-
while ( 1 )
-
{
-
sock_fd_conn = getAcceptDone (sock_fd_queue , &(client_addr) , &(client_len) ) ;
-
if ( sock_fd_conn > 0 ) break ;
-
}
-
-
printf ("get new connect request sock_fd is %d \n" , sock_fd_conn) ;
-
goto success ;
-
-
error :
-
perror ("method failed") ;
-
goto success ;
-
success :
-
return 0 ;
-
}
client端执行结果
.....
getConnectDone failed : Connection refused
waiting for server set up
.......
......
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
getConnectDone failed : Connection refused
waiting for server set up
success send connect request to server
server 端执行结果:
getSocketDone success
getBindDone success
getListenDone success
set server accepting mode non-blocking
getAcceptDone failed : Resource temporarily unavailable
get new connect request sock_fd is 4
阅读(2720) | 评论(0) | 转发(0) |