Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1477503
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类:

2012-03-04 13:55:37

原文地址:(3)Socket程序设计 作者:g_programming

3Socket程序设计

 

注:所以文章红色字体代表需要特别注意和有问题还未解决的地方,蓝色字体表示需要注意的地方

1.本文所介绍的程序平台

开发板:arm9-mini2440

虚拟机为:Red Hat Enterprise Linux 5

开发板上系统内核版本:linux-2.6.32.2

 

2.程序清单

本次实验程序为国嵌培训代码,本人作了改动和较为详细的注释,如有错误请指出。

注意:在收到的消息最后加上字符串结束符!

基于TCPsocket程序设计:

 

tcp_client.c

#include

#include

#include

#include

#include

#include

#include

#include

 

#define portnumber 3334

 

int main(int argc, char *argv[])

{

         int sockfd;

         char buffer[1024];

         struct sockaddr_in server_addr;

         struct hostent *host;

 

      /* 使用hostname查询host 名字 */

         if(argc!=2)

         {

                   fprintf(stderr,"Usage:%s hostname \a\n",argv[0]);

                   exit(1);

         }

 

         //在网络上标识一台机器可以用IP,也可以使用主机名。

         //struct hostent *gethostbyname(const char *hostname)

         if((host=gethostbyname(argv[1]))==NULL)

         {

                   fprintf(stderr,"Gethostname error\n");

                   exit(1);

         }

 

         /* 客户程序开始建立 sockfd描述符 */

         if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:Internet;SOCK_STREAM:TCP

         {

                   fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));

                   exit(1);

         }

 

         /* 客户程序填充服务端的资料 */

         bzero(&server_addr,sizeof(server_addr)); // 初始化,0

         server_addr.sin_family=AF_INET;          // IPV4

         //htons unsigned short类型从主机序转换到网络序

         server_addr.sin_port=htons(portnumber);  // (将本机器上的short数据转化为网络上的short数据)端口号

         server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址

        

         /* 客户程序发起连接请求 */

         if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

         {

                   fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));

                   exit(1);

         }

 

         /* 连接成功了 */

         printf("Please input char:\n");

        

         /* 发送数据 */

         fgets(buffer,1024,stdin);

         write(sockfd,buffer,strlen(buffer));

 

         /* 结束通讯 */

         close(sockfd);

         exit(0);

}

 

tcp_server.c

 

#include

#include

#include

#include

#include

#include

#include

#include

 

#define portnumber 3334

 

int main(int argc, char *argv[])

{

         int sockfd,new_fd;

         struct sockaddr_in server_addr;

         struct sockaddr_in client_addr;

         int sin_size;

         int nbytes;

         char buffer[1024];

        

 

         /* 服务器端开始建立sockfd描述符 */

         if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)// AF_INET:IPV4;SOCK_STREAM:TCP

         {

                   fprintf(stderr,"Socket error:%s\n\a",strerror(errno));

                   exit(1);

         }

 

         /* 服务器端填充 sockaddr结构 */

         bzero(&server_addr,sizeof(struct sockaddr_in)); // 初始化,0

         server_addr.sin_family=AF_INET;                 // Internet

         //htonl unsigned long类型从主机序转换到网络序

         server_addr.sin_addr.s_addr=htonl(INADDR_ANY);  // (将本机器上的long数据转化为网络上的long数据)和任何主机通信  //INADDR_ANY 表示可以接收任意IP地址的数据,即绑定到所有的IP

         //server_addr.sin_addr.s_addr=inet_addr("198.162.1.1");  //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip

         server_addr.sin_port=htons(portnumber);         // (将本机器上的short数据转化为网络上的short数据)端口号

        

         /* 捆绑sockfd描述符到IP地址 */

         if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

         {

                   fprintf(stderr,"Bind error:%s\n\a",strerror(errno));

                   exit(1);

         }

 

         /* 设置允许连接的最大客户端数 */

         if(listen(sockfd,5)==-1)

         {

                   fprintf(stderr,"Listen error:%s\n\a",strerror(errno));

                   exit(1);

         }

 

         while(1)

         {

                   /* 服务器阻塞,直到客户程序建立连接 */

                   sin_size=sizeof(struct sockaddr_in);

                   if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)

                   {

                            fprintf(stderr,"Accept error:%s\n\a",strerror(errno));

                            exit(1);

                   }

                   fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串

                  

                   if((nbytes=read(new_fd,buffer,1024))==-1)

                   {

                            fprintf(stderr,"Read Error:%s\n",strerror(errno));

                            exit(1);

                   }               

                   buffer[nbytes]='\0';

                   printf("Server received %s\n",buffer);

                  

                   /* 这个通讯已经结束 */

                   close(new_fd);

                   /* 循环下一个 */

         }

 

         /* 结束通讯 */

         close(sockfd);

         exit(0);

}

 

ARM平台实验:

[root@FriendlyARM /udisk]# ifconfig

eth0      Link encap:Ethernet  HWaddr 08:90:90:90:90:90

          inet addr:192.168.1.16  Bcast:192.168.1.255  Mask:255.255.255.0

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

          Interrupt:51 Base address:0x300

 

lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          UP LOOPBACK RUNNING  MTU:16436  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 

[root@FriendlyARM /udisk]# ./tcp_server &

[root@FriendlyARM /udisk]# ./tcp_client 192.168.1.16

Server get connection from 192.168.1.16 服务程序应答

Please input char: 客户程序

gongzhi

Server received gongzhi服务程序应答

[root@FriendlyARM /udisk]#

 

并发服务器设计:

 

#include

#include

#include

#include

#include

#include

#include

#include

 

#define MY_PORT 3334

 

int main(int argc ,char **argv)

{

         int listen_fd,accept_fd;

         struct sockaddr_in     client_addr;

         int n;

         int nbytes;

 

        if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0)

       {

           printf("Socket Error:%s\n\a",strerror(errno));

           exit(1);

       }

 

        bzero(&client_addr,sizeof(struct sockaddr_in));

        client_addr.sin_family=AF_INET;

        client_addr.sin_port=htons(MY_PORT);

        client_addr.sin_addr.s_addr=htonl(INADDR_ANY);

        n=1;

 

        /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */

        setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));

        if(bind(listen_fd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)

       {

           printf("Bind Error:%s\n\a",strerror(errno));

           exit(1);

       }

 

                 /* 设置允许连接的最大客户端数 */

                   //     listen(listen_fd,5);

         if(listen(listen_fd,5)==-1)

         {

                   fprintf(stderr,"Listen error:%s\n\a",strerror(errno));

                   exit(1);

         }

 

      

       while(1)

       {

                accept_fd=accept(listen_fd,NULL,NULL);

                if((accept_fd<0)&&(errno==EINTR))

                           continue;

                else if(accept_fd<0)

               {

                    printf("Accept Error:%s\n\a",strerror(errno));

                    continue;

               }

                   //子进程继承了父进程的描述符 所以利用子进程处理

                 if((n=fork())==0)

                {

                    /* 子进程处理客户端的连接 */

                    char buffer[1024];

 

                    if((nbytes=read(accept_fd,buffer,1024))==-1)

                            {

                                     fprintf(stderr,"Read Error:%s\n",strerror(errno));

                                     exit(1);

                            }               

                            buffer[nbytes]='\0';

                            printf("Server received %s\n",buffer);

                   

                    close(listen_fd);

                    close(accept_fd);

                    exit(0);

                }

                else //父进程把描述符关闭

                         close(accept_fd);

         }

}

 

(由于arm平台不好模拟并发,所以这里只贴出了代码)

 

基于UDPsocket程序设计:

 

udp_client.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define SERVER_PORT 8888

#define MAX_BUF_SIZE 1024

 

void udpc_requ(int sockfd,const struct sockaddr_in *addr,int len)

{

         char buffer[MAX_BUF_SIZE];

         int n;

         while(1)

         {      /* 从键盘读入,写到服务端 */

                   printf("Please input char:\n");

                   fgets(buffer,MAX_BUF_SIZE,stdin);

                   sendto(sockfd,buffer,strlen(buffer),0,addr,len);

                   bzero(buffer,MAX_BUF_SIZE);

         }

}

 

int main(int argc,char **argv)

{

         int sockfd;

         struct sockaddr_in addr;

 

         if(argc!=2)

         {

                   fprintf(stderr,"Usage:%s server_ip\n",argv[0]);

                   exit(1);

         }

 

         /* 建立 sockfd描述符 */

         sockfd=socket(AF_INET,SOCK_DGRAM,0);

         if(sockfd<0)

         {

                   fprintf(stderr,"Socket Error:%s\n",strerror(errno));

                   exit(1);

         }

 

         /* 填充服务端的资料 */

         bzero(&addr,sizeof(struct sockaddr_in));

         addr.sin_family=AF_INET;

         addr.sin_port=htons(SERVER_PORT);

         if(inet_aton(argv[1],&addr.sin_addr)<0)  /*inet_aton函数用于把字符串型的IP地址转化成网络2进制数字*/

         {

                   fprintf(stderr,"Ip error:%s\n",strerror(errno));

                   exit(1);

         }

 

         udpc_requ(sockfd,&addr,sizeof(struct sockaddr_in)); // 进行读写操作

         close(sockfd);

}

 

udp_server.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define SERVER_PORT 8888

#define MAX_MSG_SIZE 1024

 

void udps_respon(int sockfd)

{

         struct sockaddr_in addr;

         int addrlen,n;

         char msg[MAX_MSG_SIZE];

 

         while(1)

         {       /* 从网络上读,并写到网络上 */

                   bzero(msg,sizeof(msg)); // 初始化,清零

                   addrlen = sizeof(struct sockaddr);

                   n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr*)&addr,&addrlen); // 从客户端接收消息

                   msg[n]=0;

                   /* 显示服务端已经收到了信息 */

                   fprintf(stdout,"Server have received %s",msg); // 显示消息

         }

}

 

int main(void)

{

         int sockfd;

         struct sockaddr_in addr;

 

         /* 服务器端开始建立socket描述符 */

         sockfd=socket(AF_INET,SOCK_DGRAM,0);

         if(sockfd<0)

         {

                   fprintf(stderr,"Socket Error:%s\n",strerror(errno));

                   exit(1);

         }

 

         /* 服务器端填充 sockaddr结构 */

         bzero(&addr,sizeof(struct sockaddr_in));

         addr.sin_family=AF_INET;

         addr.sin_addr.s_addr=htonl(INADDR_ANY);

         addr.sin_port=htons(SERVER_PORT);

 

         /* 捆绑sockfd描述符 */

         if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0)

         {

                   fprintf(stderr,"Bind Error:%s\n",strerror(errno));

                   exit(1);

         }

 

         udps_respon(sockfd); // 进行读写操作

         close(sockfd);

}

 

ARM平台实验:

[root@FriendlyARM /udisk]# ifconfig eth0 192.168.1.16

[root@FriendlyARM /udisk]# ./udp_server &

[root@FriendlyARM /udisk]# ./udp_client 192.168.1.16

Please input char:

gongzhi

Server have received gongzhi

Please input char:

hh

Server have received hh

Please input char:

^C

[root@FriendlyARM /udisk]#

 

 

阅读(573) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~