Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39197
  • 博文数量: 41
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 357
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-20 16:26
文章分类

全部博文(41)

文章存档

2014年(41)

我的朋友

分类: LINUX

2014-05-10 00:36:11

linux中实现不同计算机之间的通信,通常采用socket实现
使用socket创建一个面向连接的c/s模型
tcp:
服务端:
1.创建套接字
int socket(int domain, int type, int protocol);
domain:网域,通常取AF_INET/PF_INET代表ipv4
type:通常为SOCK_STREAM  :tcp
SOCK_DGRAM  :udp
SOCK_RAW :原始报文,通常用在底层操作
设置套接字属性
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
解决linux端口不能重用的问题

2.绑定
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
将socket绑定到端口,这样系统才知道哪个数据包对应哪个程序

3.监听
int listen(int sockfd, int backlog);
监听端口,等待客户端的连接
backlog: 任务等待队列的长度,即同一时间可以有多少个任务等待

4.接受任务
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
将任务队列中的任务拿来处理,如果服务器接受任务,会给客户端发应答包(tcp三次握手)

5.发送接收数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
6.关闭套接字
int shutdown(int sockfd, int how);
int close(int fd);

客户端:
创建socket
连接int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
发送接收send、recv
关闭

SERVER:

#include          
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

void *do_client(void *arg);

int main(int argc,char **argv)
{
 int servfd;
 int ret;
 pthread_t tid;

 //调用socket函数创建套接字。
 servfd = socket(AF_INET,SOCK_STREAM,0);
 if(-1 == servfd)
 {
  perror("socket");
  return -1;
 }

 //填充地址信息(服务器)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET; 
 servaddr.sin_port = htons(7777);
 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
 socklen_t len = sizeof(servaddr);

 
 ret = bind(servfd,(struct sockaddr *)&servaddr,len);
 if(-1 == ret)
 {
  perror("bind");
  return -1;
 }

 //调用listen启动监听
 ret = listen(servfd,100);
 if(-1 == ret)
 {
  perror("listen");
  return -1;
 }

 
 int clifd;
 struct sockaddr_in cliaddr;
 while(1)
 {
  memset(&cliaddr,0,sizeof(cliaddr));
  clifd = accept(servfd,(struct sockaddr *)&cliaddr,&len);
  if(-1 == clifd)
  {
   perror("accept");
   return -1;
  }
  printf("%d is connect success......\n",clifd);
  printf("ip  :  %s\n",inet_ntoa(cliaddr.sin_addr));
  printf("port:  %d\n",ntohs(cliaddr.sin_port));

 
  ret = pthread_create(&tid,NULL,do_client,&clifd);
  if(0 != ret)
  {
   perror("pthread_create");
   return -1;
  }
  pthread_detach(tid);
 }
 
 //调用close关闭连接。
 close(servfd);
 close(clifd);

 return 0;
}

void *do_client(void *arg)
{
 int clifd;
 int ret;
 char buf[102] = {0};

 clifd = *(int *)arg;
 
 while(1)
 {
  memset(buf,0,sizeof(buf));
  ret = read(clifd,buf,sizeof(buf)-1);
  if(ret > 0)
  {
   printf("recv message:%s\n",buf);
   write(clifd,"HI\n",strlen("HI\n"));
  }
 }


 return (void *)0;
}

CLIENT:

#include           /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define BUFSZ 1024

int main(void)
{
 int clifd;
 int ret;
 char buf[BUFSZ] = {0};
 struct pollfd pfd[2] = {0};

 //调用socket函数创建套接字。
 clifd = socket(AF_INET,SOCK_STREAM,0);
 if(-1 == clifd)
 {
  perror("socket");
  return -1;
 } 

 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET; 
 servaddr.sin_port = htons(7777);
 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
 socklen_t len = sizeof(servaddr);

 
 ret = connect(clifd,(struct sockaddr *)&servaddr,len);
 if(-1 == ret)
 {
  perror("connext");
  return -1;
 }
 
 pfd[0].fd = 0;
 pfd[1].fd = clifd;
 pfd[0].events = pfd[1].events = POLLIN;
 while(1)
 {
  ret = poll(pfd,2,-1);
  if(ret > 0)
  {
   if(pfd[0].revents == POLLIN)
   {
    //读终端
    memset(buf,0,sizeof(buf));
    ret = read(pfd[0].fd,buf,sizeof(buf)-1);
    if(ret > 0)
    {
     buf[ret] = '\0';
     write(clifd,buf,ret);
    }
   }
   
   if(pfd[1].revents == POLLIN)
   {
    //读套接字
    memset(buf,0,sizeof(buf));
    ret = read(pfd[1].fd,buf,sizeof(buf)-1);
    if(ret > 0)
    {
     buf[ret] = '\0';
     printf("server say:%s\n",buf);
    }
   }
  }
  else if(ret == 0)
  {
   printf("超时。。。。\n");
   return -1;
  }
  else
  {
   perror("poll");
   return -1;
  }
 }
 close(clifd);

 return 0;
}




udp例子:
sendto发送数据
recvfrom接收数据
server:
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16 #include
 17 #include
 18 #define MYPORT 5000
 19 #define MAXBUFLEN 100
 20
 21 int main()
 22 {
 23     int sockfd;
 24     int opt = 1;
 25     socklen_t optlen = sizeof(opt);
 26     struct sockaddr_in my_addr;
 27     struct sockaddr_in their_addr;
 28     int addr_len;
 29     int numbytes;
 30     char buf[MAXBUFLEN];
 31
 32     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
 33     {
 34         perror("socket");
 35         exit(1);
 36     }
 37     //解决linux端口不能重用的问题
 38     if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, optlen) == -1)
 39     {
 40         herror("setsockopt");
 41         exit(1);
 42     }
 43
 44     my_addr.sin_family = AF_INET;//设置本机信息
 45     my_addr.sin_port = htons(MYPORT);
 46     my_addr.sin_addr.s_addr = INADDR_ANY;
 47     bzero(&(my_addr.sin_zero), 8);
 48     //绑定端口
 49     if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
 50     {
 51         perror("bind");
 52         exit(1);
 53     }
 54
 55     addr_len = sizeof(struct sockaddr);
 56     if((numbytes = recvfrom(sockfd, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_    len)) == -1)
 57     {//接收数据
 58         perror("recvfrom");
 59         exit(1);
 60     }
 61
 62     printf("got packet form %s\n", inet_ntoa(their_addr.sin_addr));
 63     printf("packet is %d bytes long\n", numbytes);
 64     buf[numbytes] = '\0';
 65     printf("packet contains\"%s\"\n", buf);
 66
 67     close(sockfd);
 68
 69     return 0;
 70 }
client:
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16 #include
 17 #include
 18 #include
 19 #define MYPORT 5000
 20 #define MAXBUFLEN 100
 21
 22 int main()
 23 {
 24     int sockfd;
 25     int opt = 1;
 26     socklen_t optlen = sizeof(opt);
 27 //  struct sockaddr_in my_addr;
 28     struct sockaddr_in their_addr;
 29 //  int addr_len;
 30     int numbytes;
 31     char buf[MAXBUFLEN] = "talker send to listener!";
 32
 33     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
 34     {
 35         perror("socket");
 36         exit(1);
 37     }
 38     //解决linux端口不能重用的问题
 39     if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, optlen) == -1)
 40     {
 41         herror("setsockopt");
 42         exit(1);
 43     }
 44
 45     their_addr.sin_family = AF_INET;//设置本机信息
 46     their_addr.sin_port = htons(MYPORT);
 47     their_addr.sin_addr.s_addr = inet_addr("192.168.15.243");
 48     bzero(&(their_addr.sin_zero), 8);
 49     //绑定端口
 50 /*  if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
 51     {
 52         perror("bind");
 53         exit(1);
 54     }
 55 */
 56 //  addr_len = sizeof(struct sockaddr);
 57 //  
 58     if((numbytes = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&their_addr,sizeof    (struct sockaddr))) == -1)
 59     {//接收数据
 60         perror("sendto");
 61         exit(1);
 62     }
 63
 64     printf("send %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));
 65     close(sockfd);
 66
 67     return 0;
 68 }

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