佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 1074|回复: 16

socket的疑问。。

[复制链接]
发表于 24-11-2005 09:56 PM | 显示全部楼层 |阅读模式
我想试build 一个简单的dos based chat program,
请问下,在client side那里,是没次send 一个msg 就要create 一个socket,send了然后close 掉,还是从头到尾都只用一个socket,在program结束才close 掉那个socket?

我不会是很明白。。
回复

使用道具 举报


ADVERTISEMENT

发表于 24-11-2005 10:11 PM | 显示全部楼层
结束聊天了... 才 close 掉 socket, server 也一样.
回复

使用道具 举报

 楼主| 发表于 24-11-2005 11:01 PM | 显示全部楼层
奇怪,为何只有第一次send的msg有收到,第二次就收不到了。。



  1. // create socket
  2.         s = socket(AF_INET,SOCK_STREAM,0);

  3.         if(s==INVALID_SOCKET)
  4.         {
  5.                 printf("Can't create socket\n");
  6.                 sockEnd();
  7.                 return 2;
  8.         }

  9.         // send data
  10.         connect(s,(struct sockaddr *) &remote_addr,sizeof(struct sockaddr_in));

  11.         for (;;)
  12.         {
  13.        
  14.                 scanf("%128[^\n]",msg);
  15.                 FLUSH;
  16.                                
  17.                 if(send(s,msg,strlen(msg),0)==-1)
  18.                 {
  19.                         printf("Can't send message\n");  
  20.                        
  21.                         return 3;  
  22.                 }
  23.         
  24.                 if (strcmp(msg,"quitclient")==0)
  25.                 {
  26.                         break;
  27.                 }
  28.        
  29.         }

  30.         // close the channel
  31.         if(closesocket(s))
  32.         {
  33.                 printf("Error on closing socket\n");
  34.                 return 4;
  35.         }

复制代码
回复

使用道具 举报

 楼主| 发表于 24-11-2005 11:18 PM | 显示全部楼层
server side:


  1. /* creates socket */
  2.         s = socket(AF_INET,SOCK_STREAM,0);

  3.         if(s==INVALID_SOCKET)
  4.         {
  5.                 printf("Can't create socket\n");
  6.                 sockEnd();
  7.                 return 2;
  8.         }


  9.         /* links socket to address and port */
  10.         if(bind(s,(struct sockaddr *) &any_addr, sizeof(struct sockaddr_in))) {  
  11.        printf("Can't bind socket to address\n");  
  12.        sockEnd();   
  13.        return 3;  
  14.         }  
  15.        

  16.        
  17.                 /* listens on port; maximum 5 requests pending */
  18.                 listen(s,5);
  19.        
  20.         for(;;)
  21.         {
  22.                 /* when someone connects creates a new socket for data exchange */
  23.                 ss=accept(s,(struct sockaddr *) &any_addr,&addrlen);

  24.                 if(ss==INVALID_SOCKET) {
  25.                         perror("accept");
  26.                         return 4;
  27.                 }
  28.                 serverThread(ss);
  29.        
  30.         }

  31.         if(closesocket(s))
  32.         {
  33.                 perror("closesocket");
  34.                 return 5;
  35.         }
复制代码




  1. void serverThread(SOCKET ss)
  2. {

  3.         pid_t pid;
  4.         char buffer[BUFLEN];
  5.         int rec;
  6.         int addrlen;

  7.         addrlen=sizeof(struct sockaddr_in);
  8.         pid=getpid();
  9.         /* waits for incoming data */
  10.        
  11.                 rec=recv(ss,buffer,BUFLEN,0);
  12.                
  13.                 if(rec==-1)
  14.                 {
  15.                         printf("Can't receive messages\n");  
  16.                         sockEnd();   
  17.                         return ;  
  18.                 }
  19.                
  20.                 buffer[rec]=0x00;

  21.                 if (strcmp(buffer,"quitserver")==0)
  22.                 {
  23.                         closesocket(ss);
  24.                         exit(1);
  25.                 }
  26.                

  27.                
  28.                 puts(buffer);
  29.                        
  30.        

  31.         /* close the channel */
  32.         if(closesocket(ss))
  33.                 printf("Error on closing socket\n");
  34. }

复制代码
回复

使用道具 举报

发表于 24-11-2005 11:31 PM | 显示全部楼层
我没有做过DOS 的socket , 只尝试过wxwidgets 的, 不过, 我觉得问题应该出在server listen 那边

/* creates socket */
        s = socket(AF_INET,SOCK_STREAM,0);

        if(s==INVALID_SOCKET)
        {
                printf("Can't create socket\n";
                sockEnd();
                return 2;
        }


        /* links socket to address and port */
        if(bind(s,(struct sockaddr *) &any_addr, sizeof(struct sockaddr_in))) {  
       printf("Can't bind socket to address\n";  
       sockEnd();   
       return 3;  
        }  
      

      
                /* listens on port; maximum 5 requests pending */
                listen(s,5);
      
[colo=red]        for(;
        {
                /* when someone connects creates a new socket for data exchange */
                ss=accept(s,(struct sockaddr *) &any_addr,&addrlen);

                if(ss==INVALID_SOCKET) {
                        perror("accept";
                        return 4;
                }
                serverThread(ss);
      
        }

        if(closesocket(s))
        {
                perror("closesocket";
                return 5;
        }


当收到第一个msg 后, server 就自己在for loop 了, 所以完全听不到下一个msg 。

解决方式可能是放listen 在 for loop 里面。
回复

使用道具 举报

 楼主| 发表于 24-11-2005 11:48 PM | 显示全部楼层
好象不行。。
不过我试把recv 放在另一个infinite loop 里如下:

  1. for (;;){
  2.                 rec=recv(ss,buffer,BUFLEN,0);
  3.                        
  4.                 if(rec==-1)
  5.                 {
  6.                         printf("Can't receive messages\n");  
  7.                         sockEnd();   
  8.                         return ;  
  9.                 }
  10.                
  11.                 buffer[rec]=0x00; //put null to end of string

  12.                 if (strcmp(buffer,"quitserver")==0)
  13.                 {
  14.                         closesocket(ss);
  15.                         exit(1);
  16.                 }
  17.                
  18.                 puts(buffer);

  19.         }
复制代码



是可以不停的收msg。。不过第二个问题来了,如果我run两个client,这个server只收第一个client的msg,对第二client完全置之不理。。
回复

使用道具 举报

Follow Us
发表于 25-11-2005 12:11 AM | 显示全部楼层
原帖由 tensaix2j 于 24-11-2005 11:48 PM 发表
好象不行。。
不过我试把recv 放在另一个infinite loop 里如下:
[code]
for (;{
                rec=recv(ss,buffer,BUFLEN,0);
                       
                if(rec==-1)
                {
                        printf("Can't receive messages\n";  
                        s ...




不同client , 在server 上要开新的socket。所以, 你应该用1个port 来listen , 另外一个port 来接受msg 。

Server Algorithm

   listen on port A
   if (client request connection)
   {
     open a new port for connection  (accept)
   }

所以, 不同client 会bind 不同的port。
不过DOS socket programming 应该有多线性的command 才能做到, 你需要找找看哪一个command 可以办到。for loop应该不是解决办法
回复

使用道具 举报

 楼主| 发表于 25-11-2005 12:27 AM | 显示全部楼层
原来如此。。
好象有点头绪了,我在研究看看。。

谢谢
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 25-11-2005 01:25 AM | 显示全部楼层
有些linker的问题。。

我include了process.h ,然后在additional dependancy 也放了LIBCMT.LIB MSVCRT.LIB
为何compiler还是不认识 _beginthread 这个function..
回复

使用道具 举报

发表于 25-11-2005 02:44 AM | 显示全部楼层
原帖由 tensaix2j 于 25-11-2005 01:25 AM 发表
有些linker的问题。。

我include了process.h ,然后在additional dependancy 也放了LIBCMT.LIB MSVCRT.LIB
为何compiler还是不认识 _beginthread 这个function..


linker library 的设定呢?

LIBCMT.LIB 是static link 版, msvcrt 是dynamic link 版; 应该是选择其中之一。

你可能需要加入
#ifndef __MT
#define __MT  

或者在MSVC 的configuration 里 的#define 或other option (我不清楚因为我没有用VC)

如果是dynamic link 的话, __DLL 也要加入


注意, 是两个下划线 (underscore) __  , 不是一个。


我不会multithreading , 不太清楚正式coding 会是如何, 以上的资料是根据一般程序的compiler/linker problem来猜测。




参考这两个网页
http://msdn.microsoft.com/librar ... ._beginthreadex.asp
http://msdn.microsoft.com/librar ... .time_libraries.asp

[ 本帖最后由 jangancari 于 25-11-2005 02:47 AM 编辑 ]
回复

使用道具 举报

发表于 25-11-2005 09:24 AM | 显示全部楼层
比较ADVANCE的做法是(如果你的CLIENT有一定的数量的话)

SERVER 可以只用一个 LISTENING PORT 和一个 SENDING PORT
不过 LISTENING 时最好要用 MULTITHREAD
因为 MULTITHREAD 可以缓慢 LOOPING 的冲击
当有新的 CONNECTION 进来时 就开新的 THREAD
然后在 THREAD 里用 CLIENT 的 IP 来 CREATE 新的 CONNECTION
就这样,SERVER 可以在同时间 LISTEN TO 不同的 CLIENT
而不是一个CLIENT 罢了
回复

使用道具 举报

 楼主| 发表于 25-11-2005 05:17 PM | 显示全部楼层
...原来我忘了把runtime library 换去MT 了。。

原帖由 80cents 于 25-11-2005 09:24 AM 发表
比较ADVANCE的做法是(如果你的CLIENT有一定的数量的话)

SERVER 可以只用一个 LISTENING PORT 和一个 SENDING PORT
不过 LISTENING 时最好要用 MULTITHREAD
因为 MULTITHREAD 可以缓慢 LOOPING 的冲击
当有新 ...


我简单的都做不好。。
回复

使用道具 举报

 楼主| 发表于 25-11-2005 08:16 PM | 显示全部楼层
现在出现很多莫名其妙的unresolvables..... 唉~~。。
回复

使用道具 举报

发表于 28-11-2005 02:25 AM | 显示全部楼层
原帖由 tensaix2j 于 25-11-2005 08:16 PM 发表
现在出现很多莫名其妙的unresolvables..... 唉~~。。


unresolvable symbol 是没有link 到一些library , 把那些unresolve symbol 用goolge 找microsoft 的网页, 就可以知道需要哪一个library 了。
回复

使用道具 举报

 楼主| 发表于 28-11-2005 02:35 AM | 显示全部楼层
就是以下四个。。
google过了,得不到解决。。

__RTC_Initbase
__RTC_shutdown
@RTC_CheckStackVars@8
__RTC_CheckEsp
回复

使用道具 举报

发表于 29-11-2005 09:38 AM | 显示全部楼层
原帖由 tensaix2j 于 28-11-2005 02:35 AM 发表
就是以下四个。。
google过了,得不到解决。。

__RTC_Initbase
__RTC_shutdown
@RTC_CheckStackVars@8
__RTC_CheckEsp


我也找了google 好像没有头绪 。。

你的程序一定要用VC/MFC 吗? 可以用wxwidgets 吗?
回复

使用道具 举报


ADVERTISEMENT

发表于 29-11-2005 01:54 PM | 显示全部楼层
我刚好路过此地,上来凑凑热闹。

原帖由 tensaix2j 于 28-11-2005 02:35 AM 发表
就是以下四个。。
google过了,得不到解决。。

__RTC_Initbase
__RTC_shutdown
@RTC_CheckStackVars@8
__RTC_CheckEsp


你们这么厉害都找不到,不知道我找的对不对。
不对,不要骂我,我是初学者。

http://softwareforums.intel.com/ ... amp;message.id=1617
http://www.planetamd64.com/lofiversion/index.php/t5878.html
http://blog.vckbase.com/netsin/archive/2005/06/06/6066.html
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 11-11-2024 06:58 AM , Processed in 0.120736 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表