windows操作系统中进行socket编程,服务器和客户端要各司其职,简单来说,

服务器端需要做的工作有:

1.创建套接字(socket函数)

2.锁定IP地址和端口(bind函数)

3.监听进入的链接(listen函数)

4.接受连接(accept函数)

5.收发数据(send/recv函数)

6.关闭连接(closesocket函数)

客户端需要的做的工作有:

1.创建套接字(socket函数)

2.连接到服务器端(connect函数)

3.收发数据(send/recv函数)

4.关闭连接(closesocket函数)

以下是一个简单的例子,代码是从网上找来的。但是感觉有些地方写的不够好,就稍微修改了一些地方,也勉强算原创吧。代码如下:

//Server.cpp
#include
#include

using namespace std;

#pragma comment(lib,"ws2_32.lib")

#define  PORT 4000
//#define  IP_ADDRESS "127.0.0.1"

DWORD WINAPI ClientThread(LPVOID lpParameter)
{
    SOCKET CientSocket = (SOCKET)lpParameter;
    int Ret = 0;
    char RecvBuffer[MAX_PATH];

    while ( true )
    {
        memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
        Ret = recv(CientSocket, RecvBuffer, MAX_PATH, 0);
        if ( Ret == 0 || Ret == SOCKET_ERROR )
        {
            cout<<"客户端退出!"<             break;
        }
        cout<<"接收到客户信息为:"<     }

    return 0;
}

int main(int argc, char* argv[])
{
    WSADATA  Ws;
    SOCKET ServerSocket, CientSocket;
    struct sockaddr_in LocalAddr, ClientAddr;
    int Ret = 0;
    int AddrLen = 0;
    HANDLE hThread = NULL;

    //Init Windows Socket
    if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
    {
        cout<<"Init Windows Socket Failed::"<         return -1;
    }
   
    //Create Socket
    ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( ServerSocket == INVALID_SOCKET )
    {
        cout<<"Create Socket Failed::"<         return -1;
    }

    LocalAddr.sin_family = AF_INET;
//  LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
 LocalAddr.sin_addr.s_addr = INADDR_ANY;
// INADDR_ANY 表示下面的函数bind函数把刚才创建的socket绑定到当前的电脑的IP地址上。
    LocalAddr.sin_port = htons(PORT);
    memset(LocalAddr.sin_zero, 0x00, 8);

    //Bind Socket
    Ret = bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
    if ( Ret != 0 )
    {
        cout<<"Bind Socket Failed::"<         return -1;
    }

    Ret = listen(ServerSocket, 10);
    if ( Ret != 0 )
    {
        cout<<"listen Socket Failed::"<         return -1;
    }

    cout<<"服务端已经启动"<

    while ( true )
    {
        AddrLen = sizeof(ClientAddr);
        CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
        if ( CientSocket == INVALID_SOCKET )
        {
            cout<<"Accept Failed::"<             break;
        }

        cout<<"客户端连接::"<        
        hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)CientSocket, 0, NULL);
        if ( hThread == NULL )
        {
            cout<<"Create Thread Failed!"<             break;
        }

        CloseHandle(hThread);
    }

    closesocket(ServerSocket);
    closesocket(CientSocket);
    WSACleanup();

    return 0;
}

以上是服务器端的代码,下面是客户端的代码:

//Client.cpp
#include
#include
 
using namespace std;
 
#pragma comment(lib,"ws2_32.lib")

#define  PORT 4000
//#define  IP_ADDRESS "127.0.0.1"
 
 
int main(int argc, char* argv[])
{
 WSADATA  Ws;
 SOCKET CientSocket;
 struct sockaddr_in ServerAddr;
 int Ret = 0;
 int AddrLen = 0;
 HANDLE hThread = NULL;
    char SendBuffer[MAX_PATH];

 // quick argument check
 if(argc != 2)
 {
  fprintf(stderr, "usage: %s \n", argv[0]);
  ExitProcess(1);
 }
 
    //Init Windows Socket
    if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
    {
        cout<<"Init Windows Socket Failed::"<         return -1;
    }
 
    //Create Socket
    CientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( CientSocket == INVALID_SOCKET )
    {
        cout<<"Create Socket Failed::"<         return -1;
    }
 
    ServerAddr.sin_family = AF_INET;
//   ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
 ServerAddr.sin_addr.s_addr = inet_addr(argv[1]);//输入的IP地址作为服务器端IP去连接
    ServerAddr.sin_port = htons(PORT);
    memset(ServerAddr.sin_zero, 0x00, 8);
 
    Ret = connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
    if ( Ret == SOCKET_ERROR )
    {
        cout<<"Connect Error::"<         return -1;
    }
    else
    {
        cout<<"连接成功!"<     }
 
    while ( true )
    {
        cin.getline(SendBuffer, sizeof(SendBuffer));
        Ret = send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
        if ( Ret == SOCKET_ERROR )
        {
            cout<<"Send Info Error::"<             break;
        }
    }
    
    closesocket(CientSocket);
    WSACleanup();
 
    return 0;
}

这里面有几个地方需要注意一下:

1.这是windows控制台程序(console application)

2.Server.cpp中,有这样一行代码:

LocalAddr.sin_addr.s_addr = INADDR_ANY;

这样,在后面调用bind()函数的时候,程序就会把ServerSocket绑定在本电脑的IP地址上。当然,我们也可以指定一个固定的IP地址,就比如说程序中注释起来的两行代码:

#define  IP_ADDRESS "127.0.0.1"

LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);

不过,个人感觉用INADDR_ANY是最好的了,因为后者只能和客户端在同一台电脑上测试的时候才能正常运行,如果服务器端和客户端在不同的电脑上,后者就不行了。而前者即INADDR_ANY是一直行的。

3.Client.cpp中利用下面的代码进行参数的检查:

if(argc != 2)

      {

           fprintf(stderr, "usage: %s \n", argv[0]);

           ExitProcess(1);

      }

假设客户端的可执行程序为clientSocket.exe,那么运行的时候应该遵循这样的格式:

clientSocket IP

这里的IP指的是服务器端的IP地址。

我使用VC6.0编译器编译了源代码,放在附件里面了。欢迎大家下载。

参考资料:http://www.cppblog.com/bujiwu/archive/2009/01/11/71707.aspx