2 回答
TA贡献1872条经验 获得超3个赞
Socket编程首先要包含所需的头文件Winsock2.h并工程中添加库文件ws2_32.lib.
接着加载套接字库所用函数是
WSAStartup( wVersionRequested, &wsaData ); 第一个参数代表的是所要加载的套接字库的版本,第二个参数用于存储返回的版本信息
wVersionRequested = MAKEWORD( 1, 1 );用MAKEWORD来设置版本号的值其中地位代表主版本号
TCP编程:
服务器端的编写:
1. 创建套接字
SOCKET socketSrc = socket(AF_INET, SOCK_STREAM, 0);
第一个参数:指定地址族在1.1版本中只能使用AF_INET
第二个参数:指定套接字的类型在1.1版本中指定指定两种一SOCK_STREAM流式套接字和SOCK_DREAM数据报套接字
第三个参数:指示所要使用的的协议,如果为0则自动选择合适的协议(推荐)
2. 绑定套接字
bind(socketSrc, (SOCKADDR*)&addsrc, sizeof(SOCKADDR));
第一个参数:一个未绑定的的套接字
第二个参数:通过一个SOCKADDR结构体将一个地址分配给套接字
第三个参数:第二个参数的大小长度
SOCKADDR结构体: struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
第一个成员:sin_family地址族(这个参数不使用网络字节序列,其他参数都是网络字节序列)
第二个成员:sin_port指定要绑定的端口使用htons来转换成网络字节序列因为是无符号短整型
第三个成员:in_addr的结构体用来存放地址in_addr的结构如下
struct in_addr {
union {
struct S_un_b;
struct S_un_w;
u_long S_addr;
} S_un;
};
可以看出in_addr是一个包含一个联合体的结构体,联合体可以用来存放不同类型的数据但只存放一个数据,根据选择不同而不同,我们的程序中选择的是长整型的变量S_addr来存放一个地址需用htonl来转换成为网络字节序;
l htonl和htons区别是在于一个是将一个32位的主机字节序列转换成32位的TCP/IP的网络字节序一个则是16位
l inet_addr的用处是将一个点分制的IP地址字符串转换为一个合适的 in_addr的变量。
l inet_ntoa将一个网络地址转换为标准的点分式地址格式的字符串
3. 监听套接字:
listen(socketSrc, 5); //listen用于将一个已绑定但未连接的套接字对象设定成监听模式等 到一个即将到来的连接
第二个参数:表示等待连接的最大长度,如果参数被设置为SOMAXCONN将被设成一个最大的可能值
4. 接受连接:
在一个被设置为监听的套接字上允许一个连接,并返回一个已连接的新的套接字
SOCKET socketconn = accept(socketSrc, (SOCKADDR*)&addclient, &len);
第一个参数:一个被设置为监听状态的套接字;
第二个参数:一个SOCKADDR结构体用于保存请求连接的实体的地址,根据地址族的不同所创建的结构体不一样
第三个参数:存储地址的长度,此参数在调用accept函数前必须初始化,否则会导致调用失败
5. 完成以上工作后通过recv和send函数来接收和发送数据
recv(socketconn, recvbuf, 100, 0);
第一个参数是一个已连接的套接字
第二个参数是用来存储接收的数据的缓冲区地址
第三个参数表示缓冲区的大小
第四个参数指示接收的模式此处设为0
客户端的编写
6. 首先也是创建套接字
7. 然后在建立连接
connect(sockclient, (SOCKADDR*)&addsrc, sizeof(SOCKADDR));
第二个参数是要连接的地址,第三个参数则是地址的大小
UDP编程部分在简单的多线程聊天室的编写中详细说明
他是基于无连接的协议
所以编写服务器端时只要绑定了套接字后就可以开始传送和接受数据,而客户端则只需创建套接字就可以开始传送和接收
同过 recvfrom和sendto函数来操作
使用closesocket(m_socket);关闭一个套接字,使用WSACleanup();来释放套接字库
- 2 回答
- 0 关注
- 1025 浏览
添加回答
举报