您当前的位置 :首页 > 学习资料 > 一个简单的C语言的socket服务器和客户端程序
投稿

一个简单的C语言的socket服务器和客户端程序

2021-03-21 20:26:47 来源: 作者: 责任编辑:cncml

程序很简单,windows环境下的,客户端和服务器程序都在本机运行,在客户端输入发送给服务器的字符串,服务器收到字符串后会打印出来,同时与"abc"比较,与"abc"相同就会返给客户端,输入的是正确的,不同会告诉客户端输入时错误的。
客户端程序:client.cpp
  1. #include <winsock2.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define DEFAULT_PORT       5150
  6. #define DEFAULT_BUFFER     2048
  7.  
  8. char  szServer[128],
  9.      szMessage[1024];
  10. int  iPort    = DEFAULT_PORT;
  11.  
  12. int main()
  13. {
  14.    WSADATA      wsd;
  15.    SOCKET       sClient;
  16.    char         szBuffer[DEFAULT_BUFFER];
  17.    int          ret;
  18.     struct sockaddr_in server;
  19.     struct hostent    *host = NULL;
  20.     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
  21.     {
  22.        printf("Failed to load Winsock library!\\n");
  23.        return 1;
  24.     }
  25.    printf("Enter a string to send to server:\\n");
  26.    gets(szMessage);
  27.     // Create the socket, and attempt to connect to the server
  28.     sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  29.     if (sClient == INVALID_SOCKET)
  30.     {
  31.        printf("socket() failed: %d\\n", WSAGetLastError());
  32.        return 1;
  33.     }
  34.    server.sin_family = AF_INET;
  35.    server.sin_port = htons(iPort);
  36.    server.sin_addr.s_addr = inet_addr("127.0.0.1");
  37.  
  38.     if (connect(sClient, (struct sockaddr *)&server,
  39.        sizeof(server)) == SOCKET_ERROR)
  40.     {
  41.        printf("connect() failed: %d\\n", WSAGetLastError());
  42.        return 1;
  43.     }
  44.     // Send and receive data
  45.     ret = send(sClient, szMessage, strlen(szMessage), 0);
  46.     if (ret == SOCKET_ERROR)
  47.     {
  48.        printf("send() failed: %d\\n", WSAGetLastError());
  49.     }
  50.     else{
  51.        printf("Send '%s' \\n", szMessage);
  52.        ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);
  53.        if (ret == SOCKET_ERROR){
  54.          printf("recv() failed: %d\\n", WSAGetLastError());
  55.        }
  56.        else{
  57.          szBuffer[ret] = '\\0';
  58.          printf("RECV: '%s'\\n",szBuffer);
  59.        }
  60.     }
  61.    closesocket(sClient);
  62.  
  63.    WSACleanup();
  64.     return 0;
  65. }
复制代码
服务器程序:server.cpp
  1. #include <winsock2.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define DEFAULT_PORT       5150
  6. #define DEFAULT_BUFFER     4096
  7.  
  8. int   iPort     = DEFAULT_PORT;
  9. char   szAddress[128];
  10.  
  11. DWORD WINAPI ClientThread(LPVOID lpParam)
  12. {
  13.    SOCKET       sock=(SOCKET)lpParam;
  14.    char         szBuff[DEFAULT_BUFFER];
  15.    int          ret;
  16.  
  17.    while(1)
  18.     {
  19.        ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);
  20.        if (ret == 0)
  21.            break;
  22.        else if (ret == SOCKET_ERROR)
  23.        {
  24.            printf("recv() failed: %d\\n", WSAGetLastError());
  25.            break;
  26.        }
  27.        szBuff[ret] = '\\0';
  28.        printf("RECV: '%s'\\n", szBuff);
  29.       if(strcmp(szBuff,"abc")==0){
  30.          memcpy(szBuff,"Send the correct string!",25);
  31.        }
  32.        else{
  33.          memcpy(szBuff,"Send the wrong string!",23);
  34.        }
  35.        ret = send(sock, szBuff, strlen(szBuff), 0);
  36.        if (ret == SOCKET_ERROR){
  37.          printf("send() failed: %d\\n", WSAGetLastError());
  38.        }
  39.     }
  40.     return 0;
  41. }
  42.  
  43. int main()
  44. {
  45.    WSADATA      wsd;
  46.    SOCKET       sListen,
  47.                  sClient;
  48.    int          iAddrSize;
  49.    HANDLE       hThread;
  50.    DWORD        dwThreadId;
  51.     struct sockaddr_in local,
  52.                       client;
  53.  
  54.     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
  55.     {
  56.        printf("Failed to load Winsock!\\n");
  57.        return 1;
  58.     }
  59.     // Create our listening socket
  60.     sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  61.     if (sListen == SOCKET_ERROR)
  62.     {
  63.        printf("socket() failed: %d\\n", WSAGetLastError());
  64.        return 1;
  65.     }
  66.    local.sin_addr.s_addr = htonl(INADDR_ANY);
  67.    local.sin_family = AF_INET;
  68.    local.sin_port = htons(iPort);
  69.  
  70.     if (bind(sListen, (struct sockaddr *)&local,
  71.            sizeof(local)) == SOCKET_ERROR)
  72.     {
  73.        printf("bind() failed: %d\\n", WSAGetLastError());
  74.        return 1;
  75.     }
  76.    listen(sListen, 8);
  77.     // In a continous loop, wait for incoming clients. Once one
  78.     // is detected, create a thread and pass the handle off to it.
  79.     while (1)
  80.     {
  81.        iAddrSize = sizeof(client);
  82.        sClient = accept(sListen, (struct sockaddr *)&client,
  83.                        &iAddrSize);      
  84.        if (sClient == INVALID_SOCKET)
  85.        {      
  86.            printf("accept() failed: %d\\n", WSAGetLastError());
  87.            break;
  88.        }
  89.        printf("Accepted client: %s:%d\\n",
  90.            inet_ntoa(client.sin_addr), ntohs(client.sin_port));
  91.  
  92.        hThread = CreateThread(NULL, 0, ClientThread,
  93.                    (LPVOID)sClient, 0, &dwThreadId);
  94.        if (hThread == NULL)
  95.        {
  96.            printf("CreateThread() failed: %d\\n", GetLastError());
  97.            break;
  98.        }
  99.        CloseHandle(hThread);
  100.     }
  101.    closesocket(sListen);
  102.    
  103.    WSACleanup();
  104.     return 0;
  105. }
复制代码
 
  1. 作为服务器,你要绑定【bind】到本地的IP地址上进行监听【listen】,但是你的机器上可能有多块网卡,也就有多个IP地址,这时候你要选择绑定在哪个IP上面,如果指定为INADDR_ANY,那么系统将绑定默认的网卡【即IP地址】。
  2.  
  3. 作为客户端,你要连接【connect】到远端的服务器,也是要指定远端服务器的(ip, port)对。
  4. 当然,在这种情况下,不可能将IP地址指定为INADDR_ANY,系统会疯掉的。
  5.  
  6. Server:
  7. #include <winsock2.h>
  8. #pragma comment(lib, "WS2_32.lib")
  9.  
  10. #include <stdio.h>
  11. void main()
  12. {
  13.     WORD wVersionRequested;//版本号
  14.     WSADATA wsaData;
  15.     int err;
  16.  
  17.     wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
  18.     //加载套接字库,如果失败返回
  19.     err = WSAStartup(wVersionRequested, &wsaData);
  20.     if (err != 0)
  21.     {
  22.         return;
  23.     }
  24.  
  25.     //判断高低字节是不是2,如果不是2.2的版本则退出
  26.     if (LOBYTE(wsaData.wVersion) != 2 ||
  27.          
  28.         HIBYTE(wsaData.wVersion) != 2)
  29.          
  30.     {
  31.         return;
  32.     }
  33.      
  34.          //创建流式套接字,基于TCP(SOCK_STREAM)
  35.  
  36.          SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
  37.  
  38.          //Socket地址结构体的创建
  39.  
  40.          SOCKADDR_IN addrSrv;
  41.  
  42.          addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格
  43.          addrSrv.sin_family = AF_INET;//指定地址簇
  44.          addrSrv.sin_port = htons(6000);
  45.         //指定端口号,除sin_family参数外,其它参数都是网络字节序,因此需要转换
  46.  
  47.          //将套接字绑定到一个端口号和本地地址上
  48.          bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必须用sizeof,strlen不行
  49.  
  50.          listen(socSrv, 5);
  51.          
  52.          SOCKADDR_IN addrClient;//字义用来接收客户端Socket的结构体
  53.  
  54.          int len = sizeof(SOCKADDR);//初始化参数,这个参数必须进行初始化,sizeof
  55.  
  56.          //循环等待接受客户端发送请求
  57.  
  58.          while (1)
  59.          {
  60.                    //等待客户请求到来;当请求到来后,接受连接请求,
  61.  
  62.                    //返回一个新的对应于此次连接的套接字(accept)。
  63.                    //此时程序在此发生阻塞
  64.  
  65.                    SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
  66.  
  67.                    char sendBuf[100];
  68.  
  69.                    sprintf(sendBuf, "Welcome %s to JoyChou",
  70.  
  71.                             inet_ntoa(addrClient.sin_addr));//格式化输出
  72.  
  73.                    //用返回的套接字和客户端进行通信
  74.  
  75.                    send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多发送一个字节
  76.  
  77.                    //接收数据
  78.  
  79.                    char recvBuf[100];
  80.  
  81.                    recv(sockConn, recvBuf, 100, 0);
  82.  
  83.                    printf("%s\\n", recvBuf);
  84.                    closesocket(sockConn);
  85.  
  86.          }
  87. }
  88.  
  89.  
  90. Client:
  91.  
  92. #include <winsock2.H>
  93. #pragma comment(lib, "Ws2_32.lib")
  94. #include <stdio.h>
  95. #include <string.h>
  96.  
  97. void main()
  98. {   
  99.     WORD wVersionRequested;
  100.     WSADATA wsaData;
  101.     int err;
  102.      
  103.     wVersionRequested = MAKEWORD( 2, 2 );
  104.      
  105.     err = WSAStartup( wVersionRequested, &wsaData );
  106.     if ( err != 0 ) {
  107.          
  108.         return;
  109.     }
  110.      
  111.      
  112.     if ( LOBYTE( wsaData.wVersion ) != 2 ||
  113.         HIBYTE( wsaData.wVersion ) != 2 )
  114.     {
  115.          
  116.         WSACleanup( );
  117.         return;
  118.     }
  119.     SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0);
  120.     SOCKADDR_IN addrSrv;
  121.     addrSrv.sin_family = AF_INET;
  122.     addrSrv.sin_port = htons(6000);
  123.     addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.101");//服务器端的IP地址
  124.      
  125.     connect(socketClient, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
  126.     char recvBuf[256];
  127.     char sendBuf[] = "This is Joychou";
  128.     recv(socketClient, recvBuf, 256, 0);
  129.     printf("%s\\n", recvBuf);
  130.     send(socketClient, sendBuf, strlen(sendBuf) + 1, 0);
  131.     closesocket(socketClient);
  132.     WSACleanup();
  133.      
  134. }
复制代码

 
文章来源: 责任编辑:cncml
版权声明:
1、本主题所有言论和图片纯属会员个人意见,与本网站立场无关
2、本站所有主题由该文章作者发表,该文章作者与享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、管理员和版主有权不事先通知发贴者而删除本文
不良信息举报信箱 新闻热线:18733599993 技术服务:18733599993 网上投稿
关于本站 | 广告服务 | 免责申明 | 招聘信息 | 联系我们
在线网 版权所有 Copyright(C)2005-2025