📄 vcclient.c
字号:
/* vcclient.c client */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /* sockaddr_in 结构体 */
/* 下面的这个include可以使程序查询主机名字列表,找出所有与其相关的hostname */
#include <netdb.h> /* /etc/hosts 列表 */
main (argc, argv)
int argc;
char *argv[];
/* 需要的命令行参数说明:Expected command line parameters:
argv[0] - 可执行的名称
argv[1] - 目的连接主机名
argv[2] - 客户端将要用到的端口号,这个值将由服务器端给定
尽管不是必须的,调试连接代码也是非常有用的。例如,如果主机名(argv[1])
被设置为"localhost",客户端程序和服务器端程序都将在同一个系统中运
行,但是网络的连接代码同样可以练习。 */
{
int sock, /* 套接字描述符 */
val, /* 临时变量 */
cnt; /* I/O缓冲区个数 */
struct sockaddr_in myname; /* Internet套接字名称(addr) */
struct sockaddr_in *nptr; /* 获取端口号的指针 */
char buf[80]; /* I/O 缓冲区 */
/* 下面查找 /etc/hosts 文件 */
struct hostent *hp, *gethostbyaddr();
/* 检查用户输入的所有命令行参数。将argv[2]转换成整型,并把它拷贝
到myname结构体的sin_port参数中作为端口号。调用htons函数把
这个值用网络字节顺序存放 */
if ( argc < 3 ) {
printf("network client failure: required parameters");
printf(" missing from the command line\n");
printf("network client: usage");
printf("[executable-name] [host name] [port number]\n");
exit(1);
}
/* 建立一个客户套接字请求服务 */
if (( sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
printf("network client socket failure %d\n", errno);
perror("network client");
exit(2);
}
/* 把用户提供的端口号转换为整型。 */
myname.sin_port = htons( atoi(argv[2]) ); /* 服务器端口号 */
myname.sin_family = AF_INET; /* 定义为Internet范围 */
/* 这里打印出域名和转换过的端口号 */
printf("network client %s will try to connect to host %s\n",
argv[0], argv[1]);
printf("network client %s will use port number %d\n",
argv[0], ntohs ( myname.sin_port ) );
/* 获取主机信息. */
hp = gethostbyname ( argv[1] );
/* 在一切运行正常的情况下请不要删除这个值,或许它在以后能用到。
也可以把它放在注释中。 */
if ( hp == NULL ) {
printf("network client gethostbyname failure %d\n",
errno);
perror("network client");
close ( sock );
exit(3);
}
else {
printf("\nServer information obtained via");
printf(" gethostbyname:\n");
printf("\tThe official host name is %s\n", hp -> h_name);
printf("\tThe address type is %d\n", hp -> h_addrtype);
printf("\tThe length of the address is %d bytes\n",
hp -> h_length);
printf("\tThe first host address is %lx\n",
ntohl ( * (int * ) hp -> h_addr_list[0] ) );
printf("\tAlias names for the host are:\n");
while ( *hp -> h_aliases )
printf( "\t\t%s\n", *hp -> h_aliases++ );
}
/* 如果是在UNIX system V中请用memcpy代替bcopy函数 */
bcopy ( hp -> h_addr_list[0], &myname.sin_addr.s_addr,
hp -> h_length );
/* memcpy ( &myname.sin_addr.s_addr, hp -> h_addr_list[0],
hp -> h_length ); */
/* 在连接到本地或者远程服务器之前需要核实一下myname结构体中变量的值,
将它们打印出来: */
printf("\nInformation provided in client's");
printf(" connect request\n");
printf("\tRemote host address is %lx\n",
ntohl ( myname.sin_addr.s_addr ) );
printf("\tPort number supplied is %d\n",
ntohs ( myname.sin_port ) );
printf("\tInternet family ID is %d\n", myname.sin_family);
printf("\tsin_zero character string is: %s\n",
myname.sin_zero);
/* 建立与本地或者远程服务器的套接字连接 */
if ( ( connect ( sock, &myname, sizeof(myname) ) ) < 0 ) {
printf("network client %s connect failure %d\n",
argv[0], errno);
perror("network client");
close (sock);
exit(4);
}
/* 与客户端交换数据。首先清空缓冲区 */
memset (buf,0,sizeof(buf)); /* 清空缓冲区 */
/* bzero( buf, sizeof(buf)); /* 清空缓冲区, BSD 调用. */
strcpy ( buf, "Message from client to server" );
write ( sock, buf, sizeof(buf) );
/* 读取服务器发送的信息 */
if ( ( cnt = read (sock, buf, sizeof(buf) ) ) < 0 ) {
printf("network client socket read failure &d\n", errno);
perror("network client");
close(sock);
exit(5);
}
else
printf("network client received the message %s\n", buf);
/* 现在发送一个0字节的测试信息 */
/* 首先清空缓冲区 */
memset (buf,0,sizeof(buf)); /* 清空缓冲区 */
/* bzero( buf, sizeof(buf)); /* 清空缓冲区, BSD 调用. */
write ( sock, buf, 0 );
close (sock);
exit(0);
} /* end of main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -