免费注册 查看新帖 |

Chinaunix

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

请教 linux c 网络编程 server/client 程序问题 (tcp) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-12-10 16:21 |只看该作者 |倒序浏览
一 个 server/client 程序 (tcp)
client 端能与 server端连接 ,而且可以互相传递消息,

问题是 server端在 接收字符串数据时,只能接收大于设定值时(红色),才能运行完成,
想问一 下各位大大,如何才能实现  任意字符串长度 的通信啊?  先谢谢了

// accept data&
bzero((void *)data2, len);
readn(client_sockfd, (void *)data2,10);
printf("Server read line:%s\n", data2);



client 源代码如下
  1. /* File: client.c */
  2. #include <sys/types.h>;
  3. #include <sys/socket.h>;
  4. #include <netinet/in.h>;
  5. #include <errno.h>;
  6. #include <stdio.h>;
  7. #include <errno.h>;

  8. int main(int argc, char **argv)
  9. {
  10.         int fd;
  11.         struct sockaddr_in address;
  12.         int address_len;
  13.         int rtval;
  14.         char *data;
  15.         static char zx[100];
  16.         char data2[100];
  17.         int len;

  18.         //建立套接口
  19.         fd = socket(AF_INET, SOCK_STREAM, 0);

  20.         //联接
  21.         address.sin_family = AF_INET;
  22.         address.sin_addr.s_addr = inet_addr("127.0.0.1");
  23.         address.sin_port = htons(1234);
  24.         address_len = sizeof(address);

  25.         rtval = connect(fd, (struct sockaddr *) &address, address_len);
  26.         if (rtval == -1)
  27.                 exit(1);

  28.         //发送数据
  29.         printf("Client enter sth: \n");
  30.         scanf("%s", zx);
  31.         data = zx;
  32.         printf("\n");


  33.         writen(fd, (void *) data, strlen(data));
  34.         printf("Client sent line:\n%s\n", data);

  35.         //接收数据
  36.         readn(fd, (void *) data2, 100);
  37.         printf("Client read line:\n%s\n", data2);

  38.         printf("Client exit.\n");
  39.         //关闭
  40.         close(fd);
  41. }



  42. // 下面是三个函数: 读n个字节; 写n个字节; 读一行.

  43. ssize_t readn(int fd, void *vptr, size_t n)
  44. {
  45.         ssize_t nleft, nread;
  46.         char *ptr;

  47.         ptr = vptr;
  48.         nleft = n;
  49.         while (nleft >; 0) {
  50.                 if ((nread = read(fd, ptr, nleft)) < 0) {
  51.                         if (errno == EINTR)
  52.                                 nread = 0;
  53.                         else
  54.                                 return -1;
  55.                 } else if (nread == 0)
  56.                         break;        //EOF
  57.                 nleft -= nread;
  58.                 ptr += nread;
  59.         }
  60.         return (n - nleft);
  61. }

  62. ssize_t writen(int fd, void *vptr, size_t n)
  63. {
  64.         size_t nleft, nwritten;
  65.         char *ptr;

  66.         ptr = vptr;
  67.         nleft = n;

  68.         while (nleft >; 0) {
  69.                 if ((nwritten = write(fd, ptr, nleft)) <= 0) {
  70.                         if (errno == EINTR)
  71.                                 nwritten = 0;
  72.                         else
  73.                                 return -1;        //error
  74.                 }
  75.                 nleft -= nwritten;
  76.                 ptr += nwritten;
  77.         }
  78.         return n;
  79. }


  80. ssize_t readline(int fd, void *vptr, size_t maxlen)
  81. {
  82.         ssize_t n, rc;
  83.         char c, *ptr;

  84.         ptr = vptr;
  85.         for (n = 1; n < maxlen; n++) {
  86.               again:
  87.                 if ((rc = read(fd, &c, 1)) == 1) {
  88.                         *ptr++ = c;
  89.                         if (c == '\n')
  90.                                 break;        //readover
  91.                 } else if (rc == 0) {
  92.                         if (n == 1)
  93.                                 return 0;        //EOF no data read
  94.                         else
  95.                                 break;        //EOF some data read
  96.                 } else {
  97.                         if (errno == EINTR)
  98.                                 goto again;
  99.                         return -1;        //error
  100.                 }
  101.         }
  102.         *ptr = 0;
  103.         return n;
  104. }

复制代码





server1源代码
  1. /* File: server1.c */

  2. #include <stdio.h>;
  3. #include <sys/types.h>;
  4. #include <sys/socket.h>;
  5. #include <netinet/in.h>;
  6. #include <sys/time.h>;
  7. #include <errno.h>;

  8. int main(int argc, char **argv)
  9. {
  10.         int fd;
  11.         int address_len;
  12.         struct sockaddr_in address;
  13.         fd_set fdset;

  14.         // socket build
  15.         fd = socket(AF_INET, SOCK_STREAM, 0);

  16.         // bind
  17.         address.sin_family = AF_INET;
  18.         address.sin_addr.s_addr = htonl(INADDR_ANY);
  19.         address.sin_port = htons(1234);
  20.         address_len = sizeof(address);
  21.         bind(fd, (struct sockaddr *) &address, address_len);

  22.         // listen  
  23.         listen(fd, 64);


  24.         printf("waiting...");
  25.         while (1) {
  26.                 struct sockaddr_in client_address;
  27.                 int len;
  28.                 int client_sockfd;
  29.                 char *data;
  30.                 static char zx[100];
  31.                 char data2[100];
  32.                 struct timeval timeout;

  33.                 // set timeout
  34.                 timeout.tv_sec = 1;
  35.                 timeout.tv_usec = 0;

  36.                 // set fdset
  37.                 FD_ZERO(&fdset);
  38.                 FD_CLR(fd, &fdset);
  39.                 FD_SET(fd, &fdset);
  40.                 if ((select(fd + 1, &fdset, NULL, NULL, &timeout)) < 0) {
  41.                         printf("cannot select.\n");
  42.                         fflush(stdout);
  43.                 }
  44.                 if (FD_ISSET(fd, &fdset)) {
  45.                         //&connect?
  46.                         len = sizeof(client_address);
  47.                         client_sockfd = accept(fd,
  48.                                                (struct sockaddr *)
  49.                                                &client_address, &len);

  50.                         // accept data&
  51.                         bzero((void *) data2, len);
  52.                         readn(client_sockfd, (void *)data2,10);         //????????问题是不是出在这句啊????????????? : (  
  53.                         printf("Server read line:%s\n", data2);

  54.                         // post data

  55.                         printf("Server enter sth:\n");
  56.                         scanf("%s", zx);
  57.                         data = zx;
  58.                         printf("\n");

  59.                         writen(client_sockfd, (void *) data, strlen(data));
  60.                         printf("Server send line:%s\n", data);

  61.                         close(client_sockfd);
  62.                         printf("waiting...");
  63.                         fflush(stdout);
  64.                 } else {
  65.                         printf(".");
  66.                         fflush(stdout);
  67.                 }
  68.         }
  69. }



  70. // 下面是三个函数: 读n个字节; 写n个字节; 读一行.

  71. ssize_t readn(int fd, void *vptr, size_t n)
  72. {
  73.         ssize_t nleft, nread;
  74.         char *ptr;

  75.         ptr = vptr;
  76.         nleft = n;
  77.         while (nleft >; 0) {
  78.                 if ((nread = read(fd, ptr, nleft)) < 0) {
  79.                         if (errno == EINTR)
  80.                                 nread = 0;
  81.                         else
  82.                                 return -1;
  83.                 } else if (nread == 0)
  84.                         break;        //EOF
  85.                 nleft -= nread;
  86.                 ptr += nread;
  87.         }
  88.         return (n - nleft);
  89. }

  90. ssize_t writen(int fd, void *vptr, size_t n)
  91. {
  92.         size_t nleft, nwritten;
  93.         char *ptr;

  94.         ptr = vptr;
  95.         nleft = n;

  96.         while (nleft >; 0) {
  97.                 if ((nwritten = write(fd, ptr, nleft)) <= 0) {
  98.                         if (errno == EINTR)
  99.                                 nwritten = 0;
  100.                         else
  101.                                 return -1;        //error
  102.                 }
  103.                 nleft -= nwritten;
  104.                 ptr += nwritten;
  105.         }
  106.         return n;
  107. }


  108. ssize_t readline(int fd, void *vptr, size_t maxlen)
  109. {
  110.         ssize_t n, rc;
  111.         char c, *ptr;

  112.         ptr = vptr;
  113.         for (n = 1; n < maxlen; n++) {
  114.               again:
  115.                 if ((rc = read(fd, &c, 1)) == 1) {
  116.                         *ptr++ = c;
  117.                         if (c == '\n')
  118.                                 break;        //readover
  119.                 } else if (rc == 0) {
  120.                         if (n == 1)
  121.                                 return 0;        //EOF no data read
  122.                         else
  123.                                 break;        //EOF some data read
  124.                 } else {
  125.                         if (errno == EINTR)
  126.                                 goto again;
  127.                         return -1;        //error
  128.                 }
  129.         }
  130.         *ptr = 0;
  131.         return n;
  132. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2004-12-10 17:06 |只看该作者

请教 linux c 网络编程 server/client 程序问题 (tcp)

1、你的 readn 多数情况下读满指定字节才返回。

2、用 read 就可以达到你的目的。

论坛徽章:
0
3 [报告]
发表于 2004-12-10 17:13 |只看该作者

请教 linux c 网络编程 server/client 程序问题 (tcp)

先谢谢 win_hate  大哥了

1.  你的 readn 多数情况下读满指定字节才返回。
设置的是 10个
就是这段代码: readn(client_sockfd, (void *)data2,10);
后面的那三个: readn writen 还有 writeline 是 richard steverns 他老人家书上的例子.


2. 用 read 就可以达到你的目的。
是直接用 read 语句来读吗? 就是说不调用readn函数,直接在主程序中实现?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
4 [报告]
发表于 2004-12-10 17:23 |只看该作者

请教 linux c 网络编程 server/client 程序问题 (tcp)

一般一个TCP/IP包最好加一个长度,接收时先收长度,再根据长度取后继包文
read(socket, buffer, len)得到一次发送的数据,返回的结果可能少于len个,一般只在短连接中用这种办法,但包文不能太大,至少不能大于SOCKET缓冲

论坛徽章:
0
5 [报告]
发表于 2004-12-10 17:37 |只看该作者

请教 linux c 网络编程 server/client 程序问题 (tcp)

下面 是 我在机器上的运行步骤于结果:

1. 开server 端

[root@localhost root]# cd cs
[root@localhost cs]#  cd server/
[root@localhost server]#  ./server9
waiting.........


2. 开client 端 ( 在新开的另外一个终端上运行)

[root@localhost root]# cd cs
[root@localhost cs]# cd client/
[root@localhost client]# ./zx9
Client enter sth:

注: zx9 是 client 的文件名,这个时候,另一个终端 ( server 终端) 的光标停下来等待



未写完,先回家吃饭去,晚上再来问, 谢谢 楼上 两位大大了 ~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP