socket编程(一)

因为下载器涉及到socket的知识,就花了一天学习了。因为时间原因分成几部分。(这里记录上的是基于Windows平台的)

 1 #include <stdio.h>
 2 #include <winsock2.h>
 3 #pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
 4 
 5 int main(){
 6     //初始化 DLL
 7     WSADATA wsaData;
 8     WSAStartup( MAKEWORD(2, 2), &wsaData);
 9 
10     //创建套接字
11     SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
12 
13     //绑定套接字
14     sockaddr_in sockAddr;
15     memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
16     sockAddr.sin_family = PF_INET;  //使用IPv4地址
17     sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
18     sockAddr.sin_port = htons(1234);  //端口
19     bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
20 
21     //进入监听状态
22     listen(servSock, 20);
23 
24     //接收客户端请求
25     SOCKADDR clntAddr;
26     int nSize = sizeof(SOCKADDR);
27     SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
28 
29     //向客户端发送数据
30     char *str = "Hello World!";
31     send(clntSock, str, strlen(str)+sizeof(char), NULL);
32 
33     //关闭套接字
34     closesocket(clntSock);
35     closesocket(servSock);
36 
37     //终止 DLL 的使用
38     WSACleanup();
39 
40     return 0;
41 }

 

 

AF_INET 表示使用 IPv4 地址                                  SOCK_STREAM 表示使用面向连接的数据传输方式

IPPROTO_TCP 表示使用 TCP 协议

 

第19行通过 bind() 函数将套接字 serv_sock 与特定的IP地址和端口绑定,IP地址和端口都保存在 sockaddr_in 结构体中。


socket() 函数确定了套接字的各种属性,bind() 函数让套接字与特定的IP地址和端口对应起来,这样客户端才能连接到该套接字。

第22行让套接字处于被动监听状态。所谓被动监听,是指套接字一直处于“睡眠”中,直到客户端发起请求才会被“唤醒”。

第27行的 accept() 函数用来接收客户端的请求。程序一旦执行到 accept() 就会被阻塞(暂停运行),直到客户端发起请求。


和普通文件一样,socket 在使用完毕后也要用 close() 关闭。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <WinSock2.h>
 4 #pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
 5 
 6 int main(){
 7     //初始化DLL
 8     WSADATA wsaData;
 9     WSAStartup(MAKEWORD(2, 2), &wsaData);
10 
11     //创建套接字
12     SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
13 
14     //向服务器发起请求
15     sockaddr_in sockAddr;
16     memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
17     sockAddr.sin_family = PF_INET;
18     sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
19     sockAddr.sin_port = htons(1234);
20     connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
21 
22     //接收服务器传回的数据
23     char szBuffer[MAXBYTE] = {0};
24     recv(sock, szBuffer, MAXBYTE, NULL);
25 
26     //输出接收到的数据
27     printf("Message form server: %s\n", szBuffer);
28 
29     //关闭套接字
30     closesocket(sock);
31 
32     //终止使用 DLL
33     WSACleanup();
34 
35     system("pause");
36     return 0;
37 }

 

1) Windows 下的 socket 程序依赖 Winsock.dll 或 ws2_32.dll,必须提前加载。DLL 有两种加载方式

2) Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;Linux 不区分 socket 文件和普通文件,而 Windows 区分;Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。

3) Linux 下使用 read() / write() 函数读写,而 Windows 下使用 recv() / send() 函数发送和接收。

4) 关闭 socket 时,Linux 使用 close() 函数,而 Windows 使用 closesocket() 函数。

 

WinSock(Windows Socket)编程依赖于系统提供的动态链接库(DLL),有两个版本:

  • 较早的DLL是 wsock32.dll,大小为 28KB,对应的头文件为 winsock1.h;
  • 最新的DLL是 ws2_32.dll,大小为 69KB,对应的头文件为 winsock2.h。

 

使用DLL之前必须把DLL加载到当前程序,你可以在编译时加载

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

,也可以在程序运行时加载

posted @ 2018-05-10 01:03  Hk_Mayfly  阅读(394)  评论(0编辑  收藏  举报