-----初更----2018年1月29日(转载请注明出处)----

前言:

有很多人看完上一节后,一头雾水,我是谁?我在哪?我在干什么?其实socket问题就类似于把大象放进冰箱总共分几步的问题,这时候就要咬咬牙,把这两章需要用得到的函数搞明白,以后就是这些函数的伸展了

#0x01    accept()函数

accept()是服务端的函数。从上一张开始说,服务端bind之后,做好listen的准备,这时候,客户端说:喂,我要连接(connent),服务器端就要回话:喂,我知道了(accept),这就是accept的意思,当然实际使用accept函数可是非常强大呢!

我们先看一下使用方法

Linux/windows

1     SOCKADDR clntAddr;//客户端信息
2     int nSize = sizeof(SOCKADDR);//字节大小
3     SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);

可以看到,accept函数和bind()函数很像,在使用之前,需要再建立一个socket结构体,为什么呢?因为服务端作为接受嘛,可能有不同的人在叫他,他不知道谁在叫他,所以在有人叫他时候,就要拿个小本本记下来,知道张三叫了他,地址是*¥@*&¥*#,然后服务器在向这个地址回话:Hello World!这就是accept函数的作用。

#0x02    发送函数

Windows:

在windows下呢,发送嘛,不就是send嘛,没错,发送函数就是send(),只是具体用法是:

send(clntSock, str, strlen(str) + sizeof(char), NULL);

 

函数原型是

int send(
  _In_       SOCKET s,//最开始创建的套接字
  _In_ const char   *buf,//需发送的字符串
  _In_       int    len,//发送字符串的长度
  _In_       int    flags//标志位
);

 

 看完原型应该就知道怎么使用了,比较简单,还有,别问我标志位是什么用,我还不知道,尴尬,只是官方解释可以忽略。

 Linux:

linux下的原型和windows差不多,只不过没有了官方说可以忽略的选项,名字换了一下而已。

write(clnt_sock, str, sizeof(str));

 

 write有点意思,好像在哪见过,没错,这就是写入文件函数,因为在linux的思想就是一切皆文件,所以socket通信也被看做是往socket管道中写入字符,所以就有了write。

#0x03    接收函数

Windows:

windows下接收函数和发送函数参数一样,只是函数名表不一样

recv(sock, szBuffer, MAXBYTE, NULL);

 

 Linux:

Linux下也是和发送函数相反

read(sock, buffer, sizeof(buffer)-1);

 

0x04    关闭通道

Windows:

Windows下直接调用函数就可以关闭套接字

closesocket(sock);

 

sock还是最开始创建的套接字

Linux:

Linux下也是一样,只是函数不一样

close(sock);

 

0x05    图解

怎么样,现在需要用到的函数都讲完了,是不是懵逼了,其实只要弄明白每个函数是做什么的就可以了,废话不多说,直接放图

【C++】socket编程(二):最简单的socket通信(下)

有没有大彻大悟!!!这张图很好的解释了socket的工作原理,一定要把这张图吃透!!!

0x06    代码

说了一堆堆理论,是时候亮出真家伙了!!!代码才是最锋利的武器对不对,不多说直接上代码(注:一定要把前面的每个函数都弄懂在看代码,然后自己尝试写出来!)

Windows:

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

相关文章:

  • 2021-05-30
  • 2021-11-17
  • 2021-12-12
  • 2022-02-04
  • 2021-04-17
  • 2021-06-07
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-19
  • 2021-10-29
  • 2021-07-26
相关资源
相似解决方案