Chinaunix首页 | 论坛 | 博客
  • 博客访问: 159999
  • 博文数量: 36
  • 博客积分: 648
  • 博客等级: 上士
  • 技术积分: 335
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-09 15:29
文章分类

全部博文(36)

文章存档

2013年(2)

2012年(26)

2011年(8)

我的朋友

分类: C/C++

2012-09-19 00:29:52

今天想学习Windows Socket编程,也许是太想当然了,做个小实验都那么不顺利。

Windows下Socket编程主要包括以下几部分:
服务端
1、初始化Windows Socket库。
2、创建Socket。
3、绑定Socket。
4、监听。
5、Accept。
6、接收、发送数据。

客户端
1、初始化Windows Socket库。
2、创建Socket。
3、连接Socket。
4、接收、发送数据。

一 编写服务端程序 TcpServer.cpp

点击(此处)折叠或打开

  1. #include <WINSOCK2.H>
  2. #include <IOSTREAM.H>

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

  4. int main()
  5. {
  6. WSAData wsaData;
  7. WORD versionNum = MAKEWORD(2, 2);

  8. SOCKET serverSocket;
  9. sockaddr_in serverAddr;
  10. SOCKET connSocket;
  11. sockaddr_in connAddr;
  12. int connLength = 0;
  13. int PORT = 5515;

  14. // 初始化Windows Socket 2.2
  15. WSAStartup(versionNum, &wsaData);

  16. // 创建一个新的Socket来响应客户端的连接请求
  17. serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  18. // 填写服务器地址信息
  19. // 端口为5150
  20. // IP地址为INADDR_ANY,注意使用htonl将IP地址转换为网络格式
  21. serverAddr.sin_family = AF_INET;
  22. //serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  23. serverAddr.sin_addr.s_addr = inet_addr("192.168.0.101");
  24. serverAddr.sin_port = htons(PORT);

  25. // 绑定监听端口
  26. bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

  27. // 开始监听,指定最大同时连接数为5
  28. listen(serverSocket, 5);

  29. // 接受新的连接
  30. //while (connLength == 0)
  31. connLength = sizeof(sockaddr);
  32. connSocket = accept(serverSocket, (struct sockaddr*)&connAddr, &connLength);

  33. if (connSocket == INVALID_SOCKET )
  34. {
  35. cout<<"Accept Failed::"<<GetLastError()<<endl;
  36. }

  37. // 新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接,
  38. // 并关闭监听Socket,然后退出应用程序
  39. shutdown(connSocket, SD_BOTH);
  40. closesocket(connSocket);
  41. shutdown(serverSocket, SD_BOTH);
  42. closesocket(serverSocket);

  43. // 释放Windows Socket DLL的相关资源
  44. WSACleanup();
  45. return 0;
  46. }

遇到的问题:

1.编译报错

Linking...
TcpServer.obj : error LNK2001: unresolved external symbol

这个问题是库链接的问题,加上这句#pragma comment(lib, "ws2_32.lib")即可。

2.没有默认阻塞

程序执行到

connSocket = accept(serverSocket, (struct sockaddr*)&connAddr, &connLength);

时,如果没有接收到请求,则程序会默认阻塞在这里。可是,程序到这里就是一闪而过,不做停留,不等待客户端的链接请求。

问题在于connLength参数在这里做输入参数,应该赋予合适的初值。

在用这段代码的时候发现accept总是在没有连接就直接返回了:
int clientAddrLen = 0;
cSocket = accept(lSocket,(SOCKADDR*)&clientAddr,&clientAddrLen);

弄了N久后才发现是这个问题,之前看MSDN还以为第三个参数只是对外传的呢,汗
这段代码就OK了
int clientAddrLen = sizeof(SOCKADDR);
cSocket = accept(lSocket,(SOCKADDR*)&clientAddr,&clientAddrLen);

二 客户端程序 TcpClien.cpp

点击(此处)折叠或打开

  1. #include <WINSOCK2.H>
  2. #include <IOSTREAM.h>

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

  4. void main()
  5. {
  6. WSAData wsaData;

  7. SOCKET clientSocket;
  8. sockaddr_in serverAddr;
  9. int PORT = 5515;

  10. //初始化Windows Socket 2.2
  11. WSAStartup(MAKEWORD(2, 2), &wsaData);

  12. // 创建一个新的Socket来连接服务器
  13. clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  14. // 填写客户端地址信息
  15. // 端口为5150
  16. // 服务器IP地址为"136.149.3.29",注意使用inet_addr将IP地址转换为网络格式
  17. serverAddr.sin_family = AF_INET;
  18. serverAddr.sin_addr.s_addr = inet_addr("192.168.0.101");
  19. serverAddr.sin_port = htons(PORT);

  20. // 向服务器发出连接请求
  21. connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

  22. // 新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接,
  23. // 并关闭监听Socket,然后退出应用程序
  24. closesocket(clientSocket);
  25. WSACleanup();
  26. }

客户端没什么问题,设置好相应的端口号就行了。

阅读(2190) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~