今天想学习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
- #include <WINSOCK2.H>
- #include <IOSTREAM.H>
- #pragma comment(lib, "ws2_32.lib")
- int main()
- {
- WSAData wsaData;
- WORD versionNum = MAKEWORD(2, 2);
- SOCKET serverSocket;
- sockaddr_in serverAddr;
- SOCKET connSocket;
- sockaddr_in connAddr;
- int connLength = 0;
- int PORT = 5515;
- // 初始化Windows Socket 2.2
- WSAStartup(versionNum, &wsaData);
- // 创建一个新的Socket来响应客户端的连接请求
- serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- // 填写服务器地址信息
- // 端口为5150
- // IP地址为INADDR_ANY,注意使用htonl将IP地址转换为网络格式
- serverAddr.sin_family = AF_INET;
- //serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- serverAddr.sin_addr.s_addr = inet_addr("192.168.0.101");
- serverAddr.sin_port = htons(PORT);
- // 绑定监听端口
- bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
- // 开始监听,指定最大同时连接数为5
- listen(serverSocket, 5);
- // 接受新的连接
- //while (connLength == 0)
- connLength = sizeof(sockaddr);
- connSocket = accept(serverSocket, (struct sockaddr*)&connAddr, &connLength);
- if (connSocket == INVALID_SOCKET )
- {
- cout<<"Accept Failed::"<<GetLastError()<<endl;
- }
- // 新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接,
- // 并关闭监听Socket,然后退出应用程序
- shutdown(connSocket, SD_BOTH);
- closesocket(connSocket);
- shutdown(serverSocket, SD_BOTH);
- closesocket(serverSocket);
- // 释放Windows Socket DLL的相关资源
- WSACleanup();
- return 0;
- }
遇到的问题:
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
- #include <WINSOCK2.H>
- #include <IOSTREAM.h>
- #pragma comment(lib, "ws2_32.lib")
- void main()
- {
- WSAData wsaData;
- SOCKET clientSocket;
- sockaddr_in serverAddr;
- int PORT = 5515;
- //初始化Windows Socket 2.2
- WSAStartup(MAKEWORD(2, 2), &wsaData);
- // 创建一个新的Socket来连接服务器
- clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- // 填写客户端地址信息
- // 端口为5150
- // 服务器IP地址为"136.149.3.29",注意使用inet_addr将IP地址转换为网络格式
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = inet_addr("192.168.0.101");
- serverAddr.sin_port = htons(PORT);
- // 向服务器发出连接请求
- connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
- // 新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接,
- // 并关闭监听Socket,然后退出应用程序
- closesocket(clientSocket);
- WSACleanup();
- }
客户端没什么问题,设置好相应的端口号就行了。
阅读(2246) | 评论(0) | 转发(1) |