免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1154 | 回复: 0
打印 上一主题 下一主题

Linux网络编程--TCP客户端输入以及输出 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-30 21:22 |只看该作者 |倒序浏览
Request:
  Write a tcp client that connects to a server and sends anything read from STDIN to the server and anything received from the server is sent to STDOUT.

/* Generic TCP client that reads from standard input
   and forwards to a TCP socket. Also sends to stdout anything
   received from the socket.
   command line parameters identify the TCP server.
*/
#include stdio.h>    /* standard C i/o facilities */
#include stdlib.h>    /* needed for atoi() */
#include unistd.h>    /* Unix System Calls */
#include sys/types.h>    /* system data type definitions */
#include sys/socket.h> /* socket specific definitions */
#include netinet/in.h> /* INET constants and stuff */
#include arpa/inet.h>    /* IP address conversion stuff */
#include netdb.h>    /* Name lookups (gethostbyname) */
void tcp_client(int tcpsock);
/* The following must passed in on the command line:
   
      name of the server (argv[1])
      port number of the server (argv[2])
*/
int main( int argc, char **argv ) {
  int sk;
  struct sockaddr_in skaddr;
  struct hostent *hp;
  /* first - check to make sure there are 2 command line parameters
     (argc=3 since the program name is argv[0])
  */
  if (argc!=3) {
    printf("Usage: client  \n");
    exit(0);
  }
  /* create a socket
     IP protocol family (PF_INET)
     TCP protocol (SOCK_STREAM)
  */
  
  if ((sk = socket( PF_INET, SOCK_STREAM, 0 ))  0) {
    perror("Problem creating socket");
    exit(1);
  }
  /* fill in an address structure that will be used to specify
     the address of the server we want to connect to
  */
  skaddr.sin_family = AF_INET;
  if ((hp = gethostbyname(argv[1]))!=0) {
    /* Name lookup was successful - copy the IP address */
    memcpy( &skaddr.sin_addr.s_addr, hp->h_addr, hp->h_length);
  } else {
    /* Name lookup didn't work, try converting from dotted decimal */
    /*inet_aton is missing on Solaris - you need to use inet_addr! */
    skaddr.sin_addr.s_addr = inet_addr(argv[1]);
    if (skaddr.sin_addr.s_addr==-1) {
      printf("Invalid IP address: %s\n",argv[1]);
      exit(1);
    }
  }

  skaddr.sin_port = htons(atoi(argv[2]));
  /* attempt to establish a connection with the server */
  if (connect(sk,(struct sockaddr *) &skaddr,sizeof(skaddr))  0 ) {
    perror("Problem connecting socket");
    exit(1);
  }
  printf("Connected!\n");
  /* Go handle the connection */
  tcp_client(sk);
  close(sk);
  return(0);
}
/* multiplex client reads from stdin and a socket,
   forwarding whatever is received from one source to the other.
*/
#define MAXMSG 1000
void tcp_client(int tcpsock) {
  fd_set inputfds;
  char buff[MAXMSG];
  int i;
  int max;
  int watch_stdin = 1; /* Flag keeps track of status of stdin */
  /* determine the highest number file descriptor we will use */
  max = (tcpsock>STDIN_FILENO ? tcpsock : STDIN_FILENO);
  /* do this forever */
  while (1) {
    FD_ZERO(&inputfds);        /* clear out entire set */
    FD_SET(tcpsock,&inputfds);    /* add the socket to the set */
    if (watch_stdin)
      FD_SET(STDIN_FILENO,&inputfds); /* add stdin to the set */
   
    /* call select - this blocks until there is something
       to read on one of the file descriptors */
    if (select(max+1,&inputfds,NULL,NULL,NULL)0) {
      perror("select problem");
      exit(1);
    }
    /* If STDIN has something - handle it */
    if (FD_ISSET(STDIN_FILENO,&inputfds)) {
      /* Read up to MAXMSG bytes from STDIN */
      i = read(STDIN_FILENO,buff,MAXMSG);
      if (i0) {
    perror("Error reading from STDIN");
    exit(1);
      } else if (i==0) {
    /* STDIN closed (EOF) - don't quit!
     (we want to hang around and get stuff from socket)*/
    watch_stdin=0;
      } else {
    /* Write whatever we got to the socket */
    if (write(tcpsock,buff,i)0) {
     perror("Error writing to socket");
     exit(1);
    }
      }
    }
    /* If tcpsock has something - handle it */
    if (FD_ISSET(tcpsock,&inputfds)) {
      /* Read up to MAXMSG bytes from socket */
      i = read(tcpsock,buff,MAXMSG);
      if (i0) {
    perror("Error reading from socket");
    exit(1);
      } else if (i==0) {
    /* socket closed (EOF) - quit */
    break;
      } else {
    /* Write whatever we got to STDOUT */
    if (write(STDOUT_FILENO,buff,i)0) {
     perror("Error writing to STDOUT!?!");
     exit(1);
    }
      }
    }
  }
}
     

如果不明白的话,建议看看select()函数的功能。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/21684/showart_453674.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP