我说的服务器/客户端模式的单统一模型,是指一个通信端,同时扮演两种角色,既可作为服务器等待请求又可作为客户端发起请求.具体说来就是主线程开两个子线程.一个为服务线程,提供服务;一个作为客户线程,向指定目标发起连接.现在的问题是,服务线程会绑定一个端口,而客户线程也要使用这个端口,我指定的,与其它服务器通信.但是,在winsock编程中,一个端口只能被绑定一次.请问,在我的客户线程代码中,该怎么做才能固定下发送数据的、与服务线程绑定端口相同的端口去与其它目标通信?

解决方案 »

  1.   

    不好意思,我的意思是服务和客户是同一主线程的两子线程,使用绑定一地址的同一套接字,服务在其上监听,客户在其上发送数据.我想了个办法,但是有错误产生具体代码如下// csdt.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <winsock2.h>
    #pragma comment(lib,"WS2_32")
    unsigned long __stdcall client(LPVOID pC);
    unsigned long __stdcall server(LPVOID pS);LPVOID LP;
    SOCKET gCS;
    sockaddr_in local;
    int state=0; //1-client error 2-server error
               // 0-NULL  3-client success
              //4-server success
               //句柄关闭统一在主线程中
    char buf[512];
    DWORD  eNum;int main(int argc, char* argv[])
    {
    printf("Starting...\n");        WSADATA w;
    DWORD dw; int wr=WSAStartup(MAKEWORD(1,1),&w); 
            if(0!=wr) goto er;    gCS=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   
        if(INVALID_SOCKET==gCS) goto er;
        
    local.sin_family=AF_INET;
    local.sin_port=htons((u_short)20498);
           local.sin_addr.s_addr=INADDR_ANY;    if(0!=bind(gCS,(sockaddr*)&local,sizeof(local))) goto er1;
       
            CreateThread(NULL,0,server, &gCS,0,&dw);
    CreateThread(NULL,0,client, &gCS,0,&dw);
    Sleep(5000); if(state==1 || state==2) goto er;    
            printf(buf);
    re:     char a;
    scanf("%c",&a);
    closesocket(gCS);
    WSACleanup();
    return 0;
    er1:eNum=GetLastError();
    er: FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      eNum,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                      (LPTSTR) &LP,
                      0,
                      NULL
                     ); 
    printf("The error is %s\n",(char*)LP);
    goto re;
    }
    unsigned long __stdcall client(LPVOID pC) //指向要使用的socket,调用时加&
    {
    const char* servername="127.0.0.1";
    hostent *hp;
    unsigned int addr;
    sockaddr_in s;
    SOCKET conn=*(SOCKET*)pC;      if(inet_addr(servername)==INADDR_NONE)
    {
     hp=gethostbyname(servername);
    }
    else
    {
      addr=inet_addr(servername);
      hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
    }
    if(NULL==hp) goto exc; s.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
    s.sin_family=AF_INET;
    s.sin_port=htons((u_short)20498);
    if(0!=connect(conn,(sockaddr*)&s,sizeof(s))) goto exc; //注意此句
    int z;
    z=recv(conn,buf,512,0);
    buf[z]='\0';
    // printf(buf);
        
    state=3;
           return 0;
    exc:
    eNum=GetLastError();
            state=1;
    return 1;
    }unsigned long __stdcall server(LPVOID pS)
    {
    SOCKET s=*(SOCKET*)pS;
    SOCKET c;
    sockaddr_in f;
    int flen=sizeof(f); if(0!=listen(s,1)) goto exs;
            while(1)
    {
                char t[512];
                c=accept(s,(sockaddr*)&f,&flen);
        sprintf(t,"Your port is %d\n",htons((u_short)f.sin_port));
        send(c,t,strlen(t),0);
        closesocket(c);
    }
     state=4;
            return 0;
    exs:    eNum=GetLastError(); 
    state=2;
     return 2;
    }但是运行时出问题,提示是在 if(0!=connect(conn,(sockaddr*)&s,sizeof(s))) goto exc; //注意此句
    说有参数是无效的.
    请问为什么
      

  2.   

    // csdt.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <winsock2.h>
    #pragma comment(lib,"WS2_32")
    unsigned long __stdcall client(LPVOID pC);
    unsigned long __stdcall server(LPVOID pS);LPVOID LP;
    SOCKET gCS;
    sockaddr_in local;
    int state=0; //1-client error 2-server error
               // 0-NULL  3-client success
              //4-server success
               //句柄关闭统一在主线程中
    DWORD  eNum;int main(int argc, char* argv[])
    {
    printf("Starting...\n");        WSADATA w;
    DWORD dw; int wr=WSAStartup(MAKEWORD(1,1),&w); 
            if(0!=wr) goto er1;        gCS=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   
            if(INVALID_SOCKET==gCS) goto er1;
        
    local.sin_family=AF_INET;
    local.sin_port=htons((u_short)20498);
            local.sin_addr.s_addr=INADDR_ANY;        if(0!=bind(gCS,(sockaddr*)&local,sizeof(local))) goto er1;
       
            CreateThread(NULL,0,server, &gCS,0,&dw);
    CreateThread(NULL,0,client, &gCS,0,&dw);
    Sleep(5000);
    if(state==1 || state==2) goto er;    re:     char a;
    scanf("%c",&a);
    closesocket(gCS);
    WSACleanup();
    return 0;
    er1:   eNum=GetLastError();
    er:    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
         FORMAT_MESSAGE_FROM_SYSTEM |
         FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      eNum,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                        (LPTSTR) &LP,
                        0,
                        NULL
                     ); 
    printf("The error is %s\n",(char*)LP);
    goto re;
    }
    unsigned long __stdcall client(LPVOID pC) //指向要使用的socket,调用时加&
    {
    const char* servername="127.0.0.1";
    hostent *hp;
    unsigned int addr;
    sockaddr_in s;
    SOCKET conn;//=*(SOCKET*)pC;       if(inet_addr(servername)==INADDR_NONE)
    {
     hp=gethostbyname(servername);
    }
    else
    {
      addr=inet_addr(servername);
      hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
    }
    if(NULL==hp) goto exc; s.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
    s.sin_family=AF_INET;
    s.sin_port=htons((u_short)20498); sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port=htons((u_short)20499);
            local.sin_addr.s_addr=INADDR_ANY;
       conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    bind(conn,(sockaddr*)&local,sizeof(local));
    if(0!=connect(conn,(sockaddr*)&s,sizeof(s))) goto exc;

            char buf[512];
    int z;
    z=recv(conn,buf,512,0);
    buf[z]='\0';
    printf(buf);
        
    state=3;
            return 0;
    exc:
    eNum=GetLastError();
            state=1;
    return 1;
    }unsigned long __stdcall server(LPVOID pS)
    {
    SOCKET s=*(SOCKET*)pS;
    SOCKET c;
    sockaddr_in f;
    int flen=sizeof(f); if(0!=listen(s,1)) goto exs;
            while(1)
    {
              char t[512];
              c=accept(s,(sockaddr*)&f,&flen);
      sprintf(t,"Your port is %d\n",htons((u_short)f.sin_port));
      send(c,t,strlen(t),0);
      closesocket(c);
    }
     state=4;
             return 0;
    exs:     eNum=GetLastError(); 
     state=2;
     return 2;
    }
    这段又可以正确运行的.为什么上面那段不行