服务器/客户端:winsock 编程初体验

简介:

   前日看到听风大哥的帖子<初学黑客编程(1)>,写的是windows下的C/S程序的简易示例代码,顿时有了感觉。以前在linux下写过,但是不知道如何去实际应用,便放在了一边。昨晚认真的拜读、改写了一下。今日记录下来,作为保留。


   代码如下:


   服务端:

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*Service*/
#include <winsock2.h>    //初始化网络编程函数
#include <stdio.h>
#pragma comment(lib,"ws2_32")   //静态函数库的初始化
#define PORT 139                //这个是用端口扫描器扫描的结果中任选的一个
int  main( int  argc, char  *argv[])
{
     system ( "cls" );    //清屏
     //定义一个数据类型是DSADATA的wsaData的变量
     //wsaData结构被用来保存AfxSocketlnit函数返回的Windows Sockets初始化信息
     WSADATA wsaData;
     WORD  sockVersion = MAKEWORD(2,2);
     //加载winsock库,初始化系统环境,以便以后关于网络的函数调用
     if (WSAStartup(sockVersion,&wsaData)!=0)
     {
         return  -1;
     }
     //创建一个套接字,也就是我们的监听的端口
     SOCKET sListen = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
     //判断创建是否成功,失败返回INVALID_SOCKET
     if (sListen == INVALID_SOCKET)
     {
         printf ( "socket error !\n" );
         return  -1;
     }
     //在sockaddr_in结构中装入地址信息
     sockaddr_in  sin ;
     sin .sin_family = PF_INET;
     sin .sin_port = htons(PORT);   //htons:将主机无符号短整型数转换成网络字节顺序
     sin .sin_addr.S_un.S_addr = INADDR_ANY;
     //套接字和本地地址绑定
     if (bind(sListen,(LPSOCKADDR)& sin , sizeof ( sin ))==SOCKET_ERROR)
     {
         printf ( "bind error !\n" );
         closesocket(sListen);
         return  -1;
     }
     //设置套接字进入监听模式
     if (listen(sListen,1)==SOCKET_ERROR)
     {
         printf ( "listen error !\n" );
         closesocket(sListen);
         return  -1;
     }
     //接受客户端的连接请求
     sockaddr_in remoteAddr;
     SOCKET sClient;
     int  nAddrlen =  sizeof (remoteAddr);
     char  revData[255];
     printf ( "等待连接..." );
     //接受一个新连接
     sClient = accept(sListen,(SOCKADDR *)&remoteAddr,&nAddrlen);
     if (sClient == INVALID_SOCKET)
     {
         printf ( "accept error !\n" );
         closesocket(sListen);
         return  -1;
     }
     //打印出连接者的ip
     printf ( "\n接收到一个连接:%s\r\n" ,inet_ntoa(remoteAddr.sin_addr));
     int  flag = 1;
     while (flag)
     {
         //直到连接到有效数据才打印出来
         int  ret = recv(sClient,revData, sizeof (revData),0);
                                                                                                                                                                                                                                                  
         if (ret > 0)
         {
             // 为防止打印出错,把字符串结尾设为0x00
             revData[ret] = 0x00;      
             printf ( "Client : " );
             printf ( "%s\n" ,revData);
         }
         if ( strcmp (revData, "quit\0" )==0)
         {
             closesocket(sClient);
                                                                                                                                                                                                                                                                  
             closesocket(sListen);
             WSACleanup();
             exit (0);
         }
         memset (revData,0, sizeof (revData));     //清空缓冲区
         char  sendData[255];
         printf ( "Service :" );
         scanf ( "%s" ,sendData);
         //发送数据
         send(sClient,sendData, sizeof (sendData),0);
                                                                                                                                                                                                                                                  
         if ( strcmp (sendData, "quit\0" )==0)
         {
             closesocket(sClient);
                                                                                                                                                                                                                                                                  
             closesocket(sListen);
             WSACleanup();
             exit (0);
         }
         memset (sendData,0, sizeof (sendData));     //清空缓冲区
     }
     closesocket(sListen);
     WSACleanup();
     return  0;
}
/*
     调试提示:开始-->运行-->输入"cmd"-->找到生成的xxx.exe程序所在路径-->输入:xxx  就可以了
*/


   客户端:

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*Client*/
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
#define PORT 139                      //端口扫描结果任意选的一个,也可以自定义式用argv[2]参数,然后用bind()函数进行绑定
int  main( int  argc, char  *argv[])
{
     system ( "cls" );     //清屏
     WSADATA wsaData;
     WORD  sockVersion = MAKEWORD(2,2);
     //加载winsock库
     if (WSAStartup(sockVersion,&wsaData)!=0)
     {
         return  -1;
     }
     //创建套接字
     SOCKET sClient = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
     if (sClient == INVALID_SOCKET)
     {
         printf ( "socket error !\n" );
         return  -1;
     }
     //在sockaddr_in中装入服务器端的地址信息
     sockaddr_in servAddr;
     servAddr.sin_family = AF_INET;
     servAddr.sin_port = htons(PORT);
     servAddr.sin_addr.S_un.S_addr = inet_addr(argv[1]);
     //连接到服务器端
     if (connect(sClient,(sockaddr *)&servAddr, sizeof (servAddr))==SOCKET_ERROR)
     {
         printf ( "connect error !\n" );
         closesocket(sClient);
         return  -1;
     }
     printf ( "已连接到 : %s\n" ,argv[1]);
     int  flag = 1;
     while (flag)
     {
         char  sendData[255];
         printf ( "Client : " );
         scanf ( "%s" ,sendData);
         send(sClient,sendData, sizeof (sendData),0);
         if ( strcmp (sendData, "quit\0" )==0)
         {
             closesocket(sClient);
             WSACleanup();
             exit (0);
         }
         memset (sendData,0, sizeof (sendData));     //清空缓冲区
                                                                                                                                                                                                                                
         char  revData[255];
         //直到接收到有效数据才打印出来
         int  ret = recv(sClient,revData, sizeof (revData),0);
         if ( strcmp (revData, "quit\0" )==0)
         {
             closesocket(sClient);
             WSACleanup();
             exit (0);
         }
         if (ret > 0)
         {
             //为防止打印出错,字符串末尾加上0x00
             revData[ret] = 0x00;
             printf ( "Service : %s\n" ,revData);
         }
         memset (revData,0, sizeof (revData));     //清空缓冲区
     }
     closesocket(sClient);
     WSACleanup();
     return  0;
}
/*
     调试提示:开始-->运行-->输入"cmd"-->找到生成的xxx.exe程序所在路径-->输入:xxx 目标IP     就可以了
                                                                                                                                                                                                                                     
                <需要:服务端先开启,客户端再连接>
*/



   <编译环境:VC++ 6.0>


   客户端进行连接时,自己只实现了在一台电脑开两个端口进行对话,两台电脑之间试了几次未成功,实在不知道如何做。

   不满足于上面代码的简易,打算继续用进程进行改写一下,使之能够更人性化一些,结果发现windows下的进程创建并不是fork()函数那么简单,而是CreatProcess()函数,不知所云,没学过windows编程,只能暂时搁浅了。windows进程编程技术啊,一定得学会。不然以后能有啥发展前途。

   路漫漫其修远兮...吾将上下而求索。


   PS:初学黑客编程(1)帖子链接:

       http://bbs.51cto.com/thread-1048530-1.html


   


   享受阳光,享受生活。愿与大家共同进步。



本文转自 006玩命 51CTO博客,原文链接:http://blog.51cto.com/weiyuqingcheng/1377203,如需转载请自行联系原作者

相关文章
|
1月前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
1月前
|
存储 SQL 安全
什么是传统的客户端服务器模式架构
什么是传统的客户端服务器模式架构
31 0
|
1月前
|
网络协议 Python
pythonTCP客户端编程连接服务器
【4月更文挑战第6天】本教程介绍了TCP客户端如何连接服务器,包括指定服务器IP和端口、发送连接请求、处理异常、进行数据传输及关闭连接。在Python中,使用`socket`模块创建Socket对象,然后通过`connect()`方法尝试连接服务器 `(server_ip, server_port)`。成功连接后,利用`send()`和`recv()`进行数据交互,记得在通信完成后调用`close()`关闭连接,确保资源释放和程序稳定性。
|
4天前
|
网络协议 Dubbo Java
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
9 0
|
5天前
|
Ubuntu Android开发 数据安全/隐私保护
【Android平板编程】远程Ubuntu服务器Code-Server编程写代码
【Android平板编程】远程Ubuntu服务器Code-Server编程写代码
|
6天前
|
JavaScript 前端开发 搜索推荐
Vue 的服务器端渲染(SSR)和客户端渲染(CSR)在渲染过程、性能、用户体验等方面都存在显著的区别
【5月更文挑战第8天】Vue 的 SSR 和 CSR 在渲染上有明显差异。SSR 服务器端生成 HTML 返回给浏览器,提供更快首屏加载和更好的 SEO,但增加服务器负担。CSR 客户端渲染,首次加载可能较慢,但交互更流畅,开发更简单。两者各有优劣,需根据项目需求权衡选择。
12 2
|
12天前
|
Apache 项目管理 数据安全/隐私保护
Windows安装TortoiseSVN客户端结合Cpolar实现公网提交文件到本地服务器
Windows安装TortoiseSVN客户端结合Cpolar实现公网提交文件到本地服务器
|
13天前
|
Apache 项目管理 数据安全/隐私保护
TortoiseSVN客户端如何安装配置并实现公网访问服务端提交文件到本地服务器
TortoiseSVN客户端如何安装配置并实现公网访问服务端提交文件到本地服务器
|
14天前
|
监控 安全 持续交付
【专栏】Webhook是服务器主动发送事件通知的机制,打破传统客户端轮询模式,实现数据实时高效传递。
【4月更文挑战第29天】Webhook是服务器主动发送事件通知的机制,打破传统客户端轮询模式,实现数据实时高效传递。常用于持续集成部署、第三方服务集成、实时数据同步和监控告警。具有实时性、高效性和灵活性优势,但也面临安全风险和调试挑战。理解并善用Webhook能提升系统性能,广泛应用于现代软件开发和集成。
|
24天前
|
网络协议 Ubuntu Linux
iPad Pro “买后生产力” - 在iPad上远程连接服务器编程写代码【公网远程】
iPad Pro “买后生产力” - 在iPad上远程连接服务器编程写代码【公网远程】

热门文章

最新文章