unix_c++学习笔记6
内容:
* 基于TCP的socket编程
* 基于UDP的socket编程
1. 常用 socket API
* 通用套接口地址
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family; //地址协议族,如ipv4,ipv6...
char sa_data[14]; //网络地址的实际内容
};
套接口API是设计为支持通用通讯协议,TCP/IP只是其中的一种
大部分的函数接受该结构的指针作为参数
实际使用中,用特定的协议地址结构指针来代替
* IP socket 套接口地址
struct in_addr{
in_addr_t s_addr; //真正保存IP地址的地方
};
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family;
sa_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8]; //unused
};
* 字节顺序函数
(1)uint32_t htonl( uint32_t hostlong );
uint16_t htons( uint16_t hostshort );
从主机字节顺序转到网络字节顺序
(2)uint16_t ntohs( uint16_t netshort );
uint32_t ntohl( uint32_t netlong );
从网络字节顺序转到主机字节顺序
* 地址转换函数
(1)int inet_pton( int af, const char *cp, void *addr );
从点分十进制转到数字型内部地址
(2)const char *inet_ntop( int af, const void *addr, char *cp, size_t size );
从数字型内部地址转到点分十进制
2. 基于TCP的socket编程
server端步骤:
(1)获得socket
(2)调用 bind,将一个socket和ip,port绑定在一起
(3)listen, 将socket转化为一个被动的
(4)accept, 等待请求,有请求时通过三步握手,返回一个和客户连好的socket
(5)read/write
(6)close
client端步骤:
(1)获得socket
(2)connet,向server发出请求
(3)read/write
(4)close
例子:
// server端,读入client的输入内容,写回client
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
using namespace std;
int main( int argc, char* argv[] ){
// get port
if( argc != 2 ){
cout<<"USAGE: "<< argv[0] <<" port"<< endl;
exit( -1 );
}
int port = -1;
//1. ceate socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else
cout<<"create socket ok, fd = "<< fd <<endl;
//2. bind a port
port = atoi( argv[1] );
if( port < 0 ){
cout<<"unavailable port "<< endl;
exit( -1 );
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
socklen_t len = sizeof( serveraddr );
int ret = bind( fd, ( const struct sockaddr* )&serveraddr, len );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"bind ok"<<endl;
//3. listien
ret = listen( fd, 10 );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"listen ok"<<endl;
//4. accept
struct sockaddr_in clientaddr;
memset( &clientaddr, 0x00, sizeof( clientaddr ) );
socklen_t client_len=sizeof( clientaddr );
cout<<"begin accept ... "<<endl;
int clientfd = accept( fd, ( struct sockaddr* )&clientaddr, &client_len );
if( clientfd < 0 ){
cout<<"accept error"<<endl;
close( fd );
exit( -1 );
}else{
cout<<"get connection from ";
char buf[ 32 ];
memset( buf, 0x00, sizeof( buf ) );
inet_ntop( AF_INET, &clientaddr.sin_addr, buf, sizeof( buf ) );
cout<< buf <<" "<< clientaddr.sin_port <<endl;
}
//5. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
read( clientfd, buf, sizeof( buf ) );
if( strcmp( buf, "bye" )==0 ) break;
write( clientfd, buf, sizeof( buf ) );
}
//6. close socket
close( clientfd );
close( fd );
return 0;
}
// client 端, 向server发送,显示回显
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
#include<fcntl.h>
using namespace std;
int main( int argc, char* argv[] ){
// 1. get server ip and port
if( argc != 3 ){
cout<<"USAGE: "<< argv[0] <<" ip port"<<endl;
exit( -1 );
}
int port = atoi( argv[2] );
// 2. create socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else{
cout<<"create socket ok, fd = "<< fd <<endl;
}
// 3. connect server
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( port );
inet_pton( AF_INET, argv[1], &serveraddr.sin_addr );
int ret = connect( fd, ( struct sockaddr* )&serveraddr, sizeof( serveraddr ) );
if( ret < 0 ){
cout<<"connect error"<<endl;
close( fd );
exit( -1 );
}else{
cout<<"connect ok"<<endl;
}
// 4. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
cout<<"enter a line > ";
cin.getline( buf, sizeof( buf ) );
if( write( fd, buf, strlen( buf ) ) <= 0 ){
cout<<"write error"<<endl;
break;
}
if( strcmp( buf, "bye" )==0 ) break;
memset( buf, 0x00, sizeof( buf ) );
if( read( fd, buf, sizeof( buf ) ) <= 0 ){
cout<<"read error"<<endl;
break;
}
cout<<buf <<endl;
}
// 5. close
close( fd );
return 0;
}
// 上面的server只能处理一个客户请求,下面改为真正的server
// 我们用多进程,因为进程是管理员可控的,某个进程出现问题可停掉他,线程则不行
// 用fork就要想到用信号处理僵死进程,用信号就要想到信号会打断阻塞函数(这里的是accept)
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
#include<signal.h>
#include<sys/wait.h>
using namespace std;
void handler( int sig ){
pid_t pid=wait( NULL );
cout<<"child "<<pid<<" exited..."<<endl;
}
int main( int argc, char* argv[] ){
if( signal( SIGCHLD, handler )==SIG_ERR ){
cout<<"signal error"<<endl;
exit( -1 );
}
// get port
if( argc != 2 ){
cout<<"USAGE: "<< argv[0] <<" port"<< endl;
exit( -1 );
}
int port = -1;
//1. ceate socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else
cout<<"create socket ok, fd = "<< fd <<endl;
//2. bind a port
port = atoi( argv[1] );
if( port < 0 ){
cout<<"unavailable port "<< endl;
exit( -1 );
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
socklen_t len = sizeof( serveraddr );
int ret = bind( fd, ( const struct sockaddr* )&serveraddr, len );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"bind ok"<<endl;
//3. listien
ret = listen( fd, 10 );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"listen ok"<<endl;
//4. accept
struct sockaddr_in clientaddr;
while( 1 ){
memset( &clientaddr, 0x00, sizeof( clientaddr ) );
socklen_t client_len=sizeof( clientaddr );
cout<<"begin accept ... "<<endl;
int clientfd = accept( fd, ( struct sockaddr* )&clientaddr, &client_len );
if( clientfd < 0 ){
cout<<"accept error"<<endl;
continue;
}else{
cout<<"get connection from ";
char buf[ 32 ];
memset( buf, 0x00, sizeof( buf ) );
inet_ntop( AF_INET, &clientaddr.sin_addr, buf, sizeof( buf ) );
cout<< buf <<" "<< clientaddr.sin_port <<endl;
}
pid_t cid=fork();
if( cid==0 ){
cout<<"child pid="<< getpid() <<endl;
//5. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
read( clientfd, buf, sizeof( buf ) );
if( strcmp( buf, "bye" )==0 ) break;
write( clientfd, buf, sizeof( buf ) );
}
//6. close socket
close( clientfd );
exit( 0 );
}
}
close( fd );
return 0;
}
3. 基于UDP的socket编程
server端步骤:
(1)获得socket
(2)bind
(3)recvfrom/sendto
(4)close
client端步骤:
(1)获得socket
(2)recvfrom/sendto
(3)close
例子:
#include<sys/socket.h>
#include<iostream>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
const int MAXLINE=256;
const int SERV_PORT=1414;
typedef struct sockaddr SA;
typedef struct sockaddr_in SA_IN;
void do_echo( int fd, SA* cli_addr, int len );
int main(){
//1. create a udp socket
int udp_fd=socket( AF_INET, SOCK_DGRAM, 0 );
if( udp_fd < 0 ){
cout<<"create error"<<endl;
exit( -1 );
}
//2. bind
SA_IN serv_addr;
memset( &serv_addr, 0x00, sizeof( serv_addr ) );
serv_addr.sin_family= AF_INET;
serv_addr.sin_port = htons( SERV_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
int ret = bind( udp_fd, (SA*)&serv_addr, sizeof( serv_addr ) );
if( ret < 0 ){
cout<<"bind error"<<endl;
close( udp_fd );
exit( -1 );
}
SA_IN cli_addr;
do_echo( udp_fd, (SA*)&cli_addr, sizeof( cli_addr ) );
return 0;
}
void do_echo( int fd, SA* cli_addr, int len ){
char buf[ MAXLINE ];
int n;
int l=len;
while( 1 ){
memset( cli_addr, 0x00, len );
memset( cli_addr, 0x00, MAXLINE );
n= recvfrom( fd, buf, MAXLINE, 0, cli_addr, (socklen_t*)&l );
cout<<"[ "<<buf<<" ]"<<endl;
sendto( fd, buf, n, 0, cli_addr, len );
}
}
#include<sys/socket.h>
#include<iostream>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
const int MAXLINE=256;
const int SERV_PORT=1414;
typedef struct sockaddr SA;
typedef struct sockaddr_in SA_IN;
void do_cli( int fd, SA* ser_addr, socklen_t len );
int main( int argc, char* argv[] ){
if( argc != 2 ){
cout<<"USAGE "<< argv[0] <<" ip"<<endl;
exit( -1 );
}
int fd = socket( AF_INET, SOCK_DGRAM, 0 );
if( fd < 0 ){
cout<<"create error"<<endl;
exit( -1 );
}
//init server address
SA_IN serv_addr;
bzero( &serv_addr, sizeof( serv_addr ) );
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( SERV_PORT );
inet_pton( AF_INET, argv[1], &serv_addr.sin_addr );
do_cli( fd, ( SA* )&serv_addr, sizeof( serv_addr ) );
}
void do_cli( int fd, SA* ser_addr, socklen_t len ){
int n;
char recvbuf[ MAXLINE ];
char sendbuf[ MAXLINE ];
while( 1 ){
memset( recvbuf, 0x00, sizeof( recvbuf ) );
memset( sendbuf, 0x00, sizeof( sendbuf ) );
cout<<"enter a line > ";
cin.getline( sendbuf, MAXLINE );
sendto( fd, sendbuf, MAXLINE, 0, ser_addr, len );
if( strcmp( sendbuf, "bye")==0 ) break;
recvfrom( fd, recvbuf, MAXLINE, 0, 0, 0 );
cout<<"[ "<<recvbuf<<" ]"<<endl;
}
}
* 基于TCP的socket编程
* 基于UDP的socket编程
1. 常用 socket API
* 通用套接口地址
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family; //地址协议族,如ipv4,ipv6...
char sa_data[14]; //网络地址的实际内容
};
套接口API是设计为支持通用通讯协议,TCP/IP只是其中的一种
大部分的函数接受该结构的指针作为参数
实际使用中,用特定的协议地址结构指针来代替
* IP socket 套接口地址
struct in_addr{
in_addr_t s_addr; //真正保存IP地址的地方
};
struct sockaddr_in{
uint8_t sin_len;
sa_family_t sin_family;
sa_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8]; //unused
};
* 字节顺序函数
(1)uint32_t htonl( uint32_t hostlong );
uint16_t htons( uint16_t hostshort );
从主机字节顺序转到网络字节顺序
(2)uint16_t ntohs( uint16_t netshort );
uint32_t ntohl( uint32_t netlong );
从网络字节顺序转到主机字节顺序
* 地址转换函数
(1)int inet_pton( int af, const char *cp, void *addr );
从点分十进制转到数字型内部地址
(2)const char *inet_ntop( int af, const void *addr, char *cp, size_t size );
从数字型内部地址转到点分十进制
2. 基于TCP的socket编程
server端步骤:
(1)获得socket
(2)调用 bind,将一个socket和ip,port绑定在一起
(3)listen, 将socket转化为一个被动的
(4)accept, 等待请求,有请求时通过三步握手,返回一个和客户连好的socket
(5)read/write
(6)close
client端步骤:
(1)获得socket
(2)connet,向server发出请求
(3)read/write
(4)close
例子:
// server端,读入client的输入内容,写回client
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
using namespace std;
int main( int argc, char* argv[] ){
// get port
if( argc != 2 ){
cout<<"USAGE: "<< argv[0] <<" port"<< endl;
exit( -1 );
}
int port = -1;
//1. ceate socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else
cout<<"create socket ok, fd = "<< fd <<endl;
//2. bind a port
port = atoi( argv[1] );
if( port < 0 ){
cout<<"unavailable port "<< endl;
exit( -1 );
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
socklen_t len = sizeof( serveraddr );
int ret = bind( fd, ( const struct sockaddr* )&serveraddr, len );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"bind ok"<<endl;
//3. listien
ret = listen( fd, 10 );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"listen ok"<<endl;
//4. accept
struct sockaddr_in clientaddr;
memset( &clientaddr, 0x00, sizeof( clientaddr ) );
socklen_t client_len=sizeof( clientaddr );
cout<<"begin accept ... "<<endl;
int clientfd = accept( fd, ( struct sockaddr* )&clientaddr, &client_len );
if( clientfd < 0 ){
cout<<"accept error"<<endl;
close( fd );
exit( -1 );
}else{
cout<<"get connection from ";
char buf[ 32 ];
memset( buf, 0x00, sizeof( buf ) );
inet_ntop( AF_INET, &clientaddr.sin_addr, buf, sizeof( buf ) );
cout<< buf <<" "<< clientaddr.sin_port <<endl;
}
//5. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
read( clientfd, buf, sizeof( buf ) );
if( strcmp( buf, "bye" )==0 ) break;
write( clientfd, buf, sizeof( buf ) );
}
//6. close socket
close( clientfd );
close( fd );
return 0;
}
// client 端, 向server发送,显示回显
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
#include<fcntl.h>
using namespace std;
int main( int argc, char* argv[] ){
// 1. get server ip and port
if( argc != 3 ){
cout<<"USAGE: "<< argv[0] <<" ip port"<<endl;
exit( -1 );
}
int port = atoi( argv[2] );
// 2. create socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else{
cout<<"create socket ok, fd = "<< fd <<endl;
}
// 3. connect server
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( port );
inet_pton( AF_INET, argv[1], &serveraddr.sin_addr );
int ret = connect( fd, ( struct sockaddr* )&serveraddr, sizeof( serveraddr ) );
if( ret < 0 ){
cout<<"connect error"<<endl;
close( fd );
exit( -1 );
}else{
cout<<"connect ok"<<endl;
}
// 4. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
cout<<"enter a line > ";
cin.getline( buf, sizeof( buf ) );
if( write( fd, buf, strlen( buf ) ) <= 0 ){
cout<<"write error"<<endl;
break;
}
if( strcmp( buf, "bye" )==0 ) break;
memset( buf, 0x00, sizeof( buf ) );
if( read( fd, buf, sizeof( buf ) ) <= 0 ){
cout<<"read error"<<endl;
break;
}
cout<<buf <<endl;
}
// 5. close
close( fd );
return 0;
}
// 上面的server只能处理一个客户请求,下面改为真正的server
// 我们用多进程,因为进程是管理员可控的,某个进程出现问题可停掉他,线程则不行
// 用fork就要想到用信号处理僵死进程,用信号就要想到信号会打断阻塞函数(这里的是accept)
#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<error.h>
#include<signal.h>
#include<sys/wait.h>
using namespace std;
void handler( int sig ){
pid_t pid=wait( NULL );
cout<<"child "<<pid<<" exited..."<<endl;
}
int main( int argc, char* argv[] ){
if( signal( SIGCHLD, handler )==SIG_ERR ){
cout<<"signal error"<<endl;
exit( -1 );
}
// get port
if( argc != 2 ){
cout<<"USAGE: "<< argv[0] <<" port"<< endl;
exit( -1 );
}
int port = -1;
//1. ceate socket
int fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 ){
cout<< strerror( errno ) <<endl;
exit( -1 );
}else
cout<<"create socket ok, fd = "<< fd <<endl;
//2. bind a port
port = atoi( argv[1] );
if( port < 0 ){
cout<<"unavailable port "<< endl;
exit( -1 );
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0x00, sizeof( serveraddr ) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
socklen_t len = sizeof( serveraddr );
int ret = bind( fd, ( const struct sockaddr* )&serveraddr, len );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"bind ok"<<endl;
//3. listien
ret = listen( fd, 10 );
if( ret < 0 ){
cout<< strerror( errno ) <<endl;
close( fd );
exit( -1 );
}else
cout<<"listen ok"<<endl;
//4. accept
struct sockaddr_in clientaddr;
while( 1 ){
memset( &clientaddr, 0x00, sizeof( clientaddr ) );
socklen_t client_len=sizeof( clientaddr );
cout<<"begin accept ... "<<endl;
int clientfd = accept( fd, ( struct sockaddr* )&clientaddr, &client_len );
if( clientfd < 0 ){
cout<<"accept error"<<endl;
continue;
}else{
cout<<"get connection from ";
char buf[ 32 ];
memset( buf, 0x00, sizeof( buf ) );
inet_ntop( AF_INET, &clientaddr.sin_addr, buf, sizeof( buf ) );
cout<< buf <<" "<< clientaddr.sin_port <<endl;
}
pid_t cid=fork();
if( cid==0 ){
cout<<"child pid="<< getpid() <<endl;
//5. read/write
char buf[ 100 ];
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
read( clientfd, buf, sizeof( buf ) );
if( strcmp( buf, "bye" )==0 ) break;
write( clientfd, buf, sizeof( buf ) );
}
//6. close socket
close( clientfd );
exit( 0 );
}
}
close( fd );
return 0;
}
3. 基于UDP的socket编程
server端步骤:
(1)获得socket
(2)bind
(3)recvfrom/sendto
(4)close
client端步骤:
(1)获得socket
(2)recvfrom/sendto
(3)close
例子:
#include<sys/socket.h>
#include<iostream>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
const int MAXLINE=256;
const int SERV_PORT=1414;
typedef struct sockaddr SA;
typedef struct sockaddr_in SA_IN;
void do_echo( int fd, SA* cli_addr, int len );
int main(){
//1. create a udp socket
int udp_fd=socket( AF_INET, SOCK_DGRAM, 0 );
if( udp_fd < 0 ){
cout<<"create error"<<endl;
exit( -1 );
}
//2. bind
SA_IN serv_addr;
memset( &serv_addr, 0x00, sizeof( serv_addr ) );
serv_addr.sin_family= AF_INET;
serv_addr.sin_port = htons( SERV_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
int ret = bind( udp_fd, (SA*)&serv_addr, sizeof( serv_addr ) );
if( ret < 0 ){
cout<<"bind error"<<endl;
close( udp_fd );
exit( -1 );
}
SA_IN cli_addr;
do_echo( udp_fd, (SA*)&cli_addr, sizeof( cli_addr ) );
return 0;
}
void do_echo( int fd, SA* cli_addr, int len ){
char buf[ MAXLINE ];
int n;
int l=len;
while( 1 ){
memset( cli_addr, 0x00, len );
memset( cli_addr, 0x00, MAXLINE );
n= recvfrom( fd, buf, MAXLINE, 0, cli_addr, (socklen_t*)&l );
cout<<"[ "<<buf<<" ]"<<endl;
sendto( fd, buf, n, 0, cli_addr, len );
}
}
#include<sys/socket.h>
#include<iostream>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
const int MAXLINE=256;
const int SERV_PORT=1414;
typedef struct sockaddr SA;
typedef struct sockaddr_in SA_IN;
void do_cli( int fd, SA* ser_addr, socklen_t len );
int main( int argc, char* argv[] ){
if( argc != 2 ){
cout<<"USAGE "<< argv[0] <<" ip"<<endl;
exit( -1 );
}
int fd = socket( AF_INET, SOCK_DGRAM, 0 );
if( fd < 0 ){
cout<<"create error"<<endl;
exit( -1 );
}
//init server address
SA_IN serv_addr;
bzero( &serv_addr, sizeof( serv_addr ) );
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( SERV_PORT );
inet_pton( AF_INET, argv[1], &serv_addr.sin_addr );
do_cli( fd, ( SA* )&serv_addr, sizeof( serv_addr ) );
}
void do_cli( int fd, SA* ser_addr, socklen_t len ){
int n;
char recvbuf[ MAXLINE ];
char sendbuf[ MAXLINE ];
while( 1 ){
memset( recvbuf, 0x00, sizeof( recvbuf ) );
memset( sendbuf, 0x00, sizeof( sendbuf ) );
cout<<"enter a line > ";
cin.getline( sendbuf, MAXLINE );
sendto( fd, sendbuf, MAXLINE, 0, ser_addr, len );
if( strcmp( sendbuf, "bye")==0 ) break;
recvfrom( fd, recvbuf, MAXLINE, 0, 0, 0 );
cout<<"[ "<<recvbuf<<" ]"<<endl;
}
}
irini
2005-10-17 21:49:56
评论:0
阅读:796
引用:0
