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

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

  代码如下:

  服务端:

  /*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 !
");

  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 !
");

  closesocket(sListen);

  return -1;

  }

  //设置套接字进入监听模式

  if(listen(sListen,1)==SOCKET_ERROR)

  {

  printf("listen error !
");

  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 !
");

  closesocket(sListen);

  return -1;

  }

  //打印出连接者的ip

  printf("
接收到一个连接:%s
",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
",revData);

  }

  if(strcmp(revData,"quit")==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)

  {

  closesocket(sClient);

  closesocket(sListen);

  WSACleanup();

  exit(0);

  }

  memset(sendData,0,sizeof(sendData));    //清空缓冲区

  }

  closesocket(sListen);

  WSACleanup();

  return 0;

  }

  /*

  调试提示:开始–>运行–>输入"cmd"–>找到生成的xxx.exe程序所在路径–>输入:xxx  就可以了

  */

  客户端:

  /*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 !
");

  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 !
");

  closesocket(sClient);

  return -1;

  }

  printf("已连接到 : %s
",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)

  {

  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)

  {

  closesocket(sClient);

  WSACleanup();

  exit(0);

  }

  if(ret > 0)

  {

  //为防止打印出错,字符串末尾加上0x00

  revData[ret] = 0x00;

  printf("Service : %s
",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

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

 

发表评论

邮箱地址不会被公开。 必填项已用*标注