+ -
当前位置:首页 → 问答吧 → 简单linux socket 编程,客户端连接不能断开。不好意思自己太大意了。。

简单linux socket 编程,客户端连接不能断开。不好意思自己太大意了。。

时间:2010-07-02

来源:互联网

本帖最后由 peijue 于 2010-07-02 18:51 编辑

server.c
  1. #include <sys/types.h>
  2. #include <pthread.h>
  3. #include <sys/socket.h>
  4. #include <netdb.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <netinet/in.h>
  8. #include <fcntl.h>
  9. #define SERVER_PORT 48888 /*定义通信端口 */
  10. #define BUF_SIZE   4096   /*定义传输数据的大小*/
  11. #define QUEUE_SIZE 10 /* 定义最大连接数 */

  12. void *work_thread(void *c)
  13. {
  14.         int sockfd = *(int*)c;
  15.         printf("thread id : %u\n", pthread_self() );
  16.         int fd, l;
  17.         char buf[BUF_SIZE];
  18.         l = recv(sockfd, buf, BUF_SIZE, 0);
  19.         printf("%s\n", buf);
  20.         if( l == -1) perror("l");
  21.         fd = open(buf, O_RDONLY);
  22.         if( fd  < 0  )
  23.         {
  24.                 printf("open file fail: %s\n", buf);
  25.                 sprintf(buf, "%s", "not the file in server\n");
  26.                 send(sockfd, buf, strlen(buf)+1, 0);
  27.                 [color=Red]close(sockfd); /* 忘了加这句,非常对不起,是我太大意了,没有关闭连接,对不起各位*/[/color]
  28.                 return (void *)1;
  29.         }
  30.         while(1)
  31.         {
  32.                 l = read(fd, buf, BUF_SIZE);
  33.                 if( l <= 0 ) break;
  34.                 send(sockfd, buf, l, 0);
  35.         }
  36.         printf("send file success\n");
  37.         close(fd);
  38.         close(sockfd);
  39.         return (void *)1;
  40. }

  41. int main( int argc, char *argv[] )
  42. {
  43.         int b, s, l, sa, fd, bytes, on = 1;
  44.         char buf[ BUF_SIZE ];  /*发送文件的缓冲区*/
  45.         struct sockaddr_in channel, addr_c;  /* 控制IP 地址的结构 */

  46.         /*--初始化套接字地址结构--*/
  47.         memset(&channel, 0, sizeof(struct sockaddr_in ) );
  48.         channel.sin_family = AF_INET;
  49.         channel.sin_addr.s_addr = htonl( INADDR_ANY  );
  50.         channel.sin_port = htons( SERVER_PORT );
  51.        

  52.         /*--创建套接字等待连接--*/

  53.         s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  54.         if( s < 0 ) perror("s");
  55.         setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on) );

  56.         b = bind( s, (struct sockaddr *)&channel, sizeof(channel) );
  57.         if( b < 0) perror("b");
  58.        
  59.         l = listen( s, QUEUE_SIZE );
  60.         int len = sizeof(struct sockaddr_in);
  61.         if( l < 0) perror("l");
  62.         /* 等待连接到来,并处理连接请求*/
  63.         while(1)
  64.         {
  65.                 int err;
  66.                 sa = accept( s, (struct sockaddr *)&addr_c, &len );/*接受一个套接字的请求*/
  67.                 if( sa < 0)
  68.                         perror("sa");       
  69.                 pthread_t tid;
  70.                 err = pthread_create(&tid, NULL, work_thread, &sa);
  71.                 if(err != 0)
  72.                 {
  73.                         printf("create thread failed");
  74.                         exit(1);
  75.                 }
  76.         }

  77. }
复制代码
client.c
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <netdb.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>

  7. #define SERVER_PORT 48888
  8. #define BUF_SIZE 4096

  9. int main(int argc, char *argv[] )
  10. {
  11.         int c, s, bytes;
  12.         char buf[BUF_SIZE];
  13.         struct hostent *h;
  14.         struct sockaddr_in channel;

  15.         if( argc != 3 ) perror("argc");
  16.         h = gethostbyname(argv[1]);

  17.         if( !h ) perror("gethostbyname failed");

  18.        
  19.         s = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
  20.         if(s<0) perror("socket");
  21.        
  22.         memset( &channel, 0, sizeof(channel) );
  23.         channel.sin_family = AF_INET;
  24.         memcpy(&channel.sin_addr.s_addr, h->h_addr, h->h_length );
  25.         channel.sin_port = htons(SERVER_PORT);

  26.         c = connect(s, (struct sockaddr *)&channel , sizeof(channel));
  27.         if(c < 0) perror("connect failed");

  28.         write(s, argv[2], strlen(argv[2])+1 );


  29.         while(1)
  30.         {
  31.                 bytes = read( s, buf, BUF_SIZE );
  32.                 if( bytes <= 0 ) break;
  33.                 write(1, buf, bytes);
  34.         }
  35. }
复制代码
初学linux下的编程,可能是线程的问题, 如果文件名正确,服务器上有这个文件就可以成功完成,要是文件不存在的话,也能发送消息回去(就是能发送错误信息给客户端, 客户端也能显示),可是为何客户的连接不能断开呢??
希望各位帮帮忙。。

作者: peijue   发布时间: 2010-07-02

补充一点,客户端 有两个参数,一个是IP,一个是文件名。
为何,ubuntu下 chrome 的字体比firefox难看呢

作者: peijue   发布时间: 2010-07-02

没看明白 要问什么

作者: ssuclinux   发布时间: 2010-07-02

就是说客户端如果输入不存在的文件名,会收到一个错误信息,可是客户端进程不会退出。

作者: peijue   发布时间: 2010-07-02

你客户端程序  判断退出的条件是 收到 负数的时候,也就是socket关闭才会退出,
你服务器没有关闭socket, 而且给客户端发信息了,客户端能接收,bytes是不会 < 0 的,
你的条件不成立,肯定不会退出

作者: ssuclinux   发布时间: 2010-07-02

回复 ssuclinux
恩 , 是这样的, 我没有关闭连接,不好意思。太大意了。。谢谢你。

作者: peijue   发布时间: 2010-07-02

热门下载

更多