一、得到主机名及其它基本信息
1.源代码
#include <stdio.h>
#include <sys/utsname.h>
int main()
{
int res;
struct utsname netInfo;
res = uname(&netInfo);
if(-1 == res)
{
printf("call unmae failed\n");
return 0;
}
else
printf("System name:%s\nNodename:%s\nRelease:%s\nVersion:%s\nMachine:%s\n",
netInfo.sysname, netInfo.nodename, netInfo.release, netInfo.version, netInfo.machine);
return 0;
}
结果如下:
System name:Linux
Nodename:GH98678
Release:3.2.0-29-generic
Version:#46-Ubuntu SMP Fri Jul 27 17:03:23 UTC 2012
Machine:x86_64
2.解释
struct utsname
{
char sysname[SYS_NMLN]; //使用的操作系统名,如:linux
char nodename[SYS_NMLN]; //网络结点主机名
char release[SYS_NMLN]; //操作系统的发布,如:linux内核为2.2.10,则为"2.2.10"
char version[SYS_NMLN]; //操作系统的版本,对于linux代表内核版本,日期
char machine[SYS_NMLN]; //主机的硬件类型,如i386
......
}
//返回值:
//调用成功:0,失败:-1,错误原因记录在errno中
二、由主机名得到IP地址
1.源代码
#include <netdb.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
if(argc != 2)
{
printf("please input domain name\n");
return 1;
}
struct hostent * ht = gethostbyname(argv[1]);
if(!ht)
printf("cann't get host information\n");
int i=0;
printf("Host:%s\n", argv[1]);
printf("Name:%s\n", ht->h_name);
printf("Type:%s\n", ht->h_addrtype==AF_INET?"AF_INET":"AF_INET6");
printf("IP Lenth:%d\n", ht->h_length);
printf("\nIP Address:\n");
char **pptr = 0;
char ipStr[80];
pptr = ht->h_addr_list;
for(;*pptr != NULL; pptr++)
{
inet_ntop(ht->h_addrtype, *pptr, ipStr, sizeof(ipStr));
printf("address:%s\n", ipStr);
}
return 1;
}
设程序名为testhost。 按下面所示,运动此程序。
./testhost www.google.com
结果如下
Host:www.google.com
Name:www.google.com
Type:AF_INET
IP Lenth:4
IP Address:
address:74.125.31.147
address:74.125.31.99
address:74.125.31.103
address:74.125.31.104
address:74.125.31.105
address:74.125.31.106
2.解释
主函数参数解释
int main(int argc, char* argv[])
argc是命令行总的参数个数+1
argv保存了程序名和命令行输入的每个参数。其中argv[0]为程序名。【1】
如下例
#include <string.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
printf("application name is:%s\n", argv[0]);
int i;
for(i=1; i<argc; i++)
{
printf("%s\n", argv[i]);
}
return 1;
}
我们在命令行执行此程序,后面不跟参数
./testhost
输出结果如下:
application name is:./testhost
我们在程序后面添加参数。参数之间以空格隔开。
./testhost linux windows qq wps
输出结果如下
application name is:./testhost
linux
windows
qq
wps
三、简单的服务端Socket程序
1.源代码
实现功能:向服务端发送消息,服务端打印消息,向客户端回馈消息。
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define TK_PORT 3339
#define MAX_BUFFER_SIZE 80
#define RECV_MSG "thanks"
int main()
{
int tcp_server_socket = socket(PF_INET, SOCK_STREAM, 0);
//<bind>
struct sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_family = PF_INET;
//convert to network byte order
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(TK_PORT);
int retBind = bind(tcp_server_socket, (struct sockaddr *)&address, sizeof(address) );
if(-1 == retBind)
{
printf("bind error\n");
exit(0);
}
//</bind>
//set passive socket
printf("listening ...\n");
listen(tcp_server_socket, 10 );
struct sockaddr_in address2;
socklen_t addressLen = sizeof(address2);
printf("accepting ...\n");
//如果等待连接队列为空 则阻塞,等待连接。
//accept 返回一个socket,可用这个socket向客户端发消息。
int clientSocket = accept(tcp_server_socket, (struct sockaddr*)&address2, &addressLen);
if( -1 == clientSocket)
{
printf("accept error\n");
exit(0);
}
printf("while ...\n");
//Receive
char buffer[MAX_BUFFER_SIZE];
ssize_t recvSize;
ssize_t setSize;
//int i = 0;
//for(i=0;i<100;i++)
while(1)
{
printf("waiting recv ...\n ");
sleep(1);
//fflush(stdout);
//recv 阻塞 直到接到消息
recvSize = recv(clientSocket, buffer, MAX_BUFFER_SIZE-1,0 );
buffer[recvSize] = '\0';
if(0 == recvSize) //客户端断开时 返回0
{
printf("bye, server\n");
break;
}
printf("Received %d bytes:%s\n", recvSize, buffer);
send(clientSocket, RECV_MSG, strlen(RECV_MSG), 0);
}
close(clientSocket); //关闭资源
return 0;
}
2.测试方法
运行此程序。程序名为ts示:please wait a moment!
运行netstat -a 查看此程序是否运行及占用端口。
使用TCP调试助手,向服务端42.121.5.59发送消息
点手动发送后,服务器显示"est socket"数据接收区显示"thanks"。
参考文档
【1】http://blog.csdn.net/lambol_8309/article/details/4524964