现在的位置: 首页 > 综合 > 正文

Linux C编程(4) 基本网络编程

2018年02月15日 ⁄ 综合 ⁄ 共 3818字 ⁄ 字号 评论关闭

一、得到主机名及其它基本信息

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 



抱歉!评论已关闭.