请选择 进入手机版 | 继续访问电脑版

[LINUX] linux socket 常用函数小结

[复制链接]
查看104 | 回复5 | 2021-9-5 00:58:40 | 显示全部楼层 |阅读模式

======== TCP ========
TCP_Server
socket()
bind()
listen()
accept()
write()
read()
close() 和shutdown()

TCP_Client
socket()
connect()
send() 和recv()
close() 和shutdown()

======== UDP ========
UDP_Server
socket()
bind()
sendto() 和recvfrom()
close() 和shutdown()

UDP_Client
socket()
sendto() 和recvfrom()
close() 和shutdown()

getpeername()
gethostname()

linux socket 常用函数小结

linux socket 常用函数小结

--------------------------------------------------------------------------------
socket()
我们使用 体系 调用socket()来获得文件形貌 符:
#include
#include
int socket(int domain, int type, int protocol);
第一个参数domain设置为“AF_INET”。
第二个参数是套接口的范例 :SOCK_STREAM或
SOCK_DGRAM。第三个参数设置为0。
体系 调用socket()只返回一个套接口形貌 符,假如 出错,则返回-1。
--------------------------------------------------------------------------------

bind()
一旦你有了一个套接口以后,下一步就是把套接口绑定到本地计算机的某一个端口上。但假如 你只想使用 connect()则无此必要。
下面是体系 调用bind()的使用 方法:
#include
#include
intbind(int sockfd, struct sockaddr* my_addr, int addrlen);
第一个参数sockfd是由socket()调用返回的套接口文件形貌 符。
第二个参数my_addr是指向数据布局 sockaddr的指针。数据布局 sockaddr中包括了关于你的地址、端口和IP地址的信息。
第三个参数addrlen可以设置成sizeof(structsockaddr)。
下面是一个例子:

  1. #include<string.h>
  2. #include<sys/types.h>
  3. #include<sys/socket.h>
  4. #define MYPORT 3490
  5. main()
  6. {
  7. int sockfd;
  8. struct sockaddr_in my_addr;
  9. sockfd=socket(AF_INET,SOCK_STREAM,0); /*do someerror checking!*/
  10. my_addr.sin_family=AF_INET; /*hostbyteorder*/
  11. my_addr.sin_port=htons(MYPORT); /*short,network byte order*/
  12. my_addr.sin_addr.s_addr=inet_addr("132.241.5.10");
  13. bzero(&(my_addr.sin_zero),8); /*zero the rest of the struct*/
  14. /*don't forget your error checking for bind():*/
  15. bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));
  16. ...
  17. }
复制代码

假如 出错,bind()也返回-1。
假如 你使用 connect()体系 调用,那么你不必知道你使用 的端标语 。当你调用connect()时,它检查套接口是否已经绑定,假如 没有,它将会分配一个空闲的端口。
--------------------------------------------------------------------------------

connect()
体系 调用connect()的用法如下:
#include
#include
int connect(int sockfd, struct sockaddr * serv_addr, int addrlen);
第一个参数还是套接口文件形貌 符,它是由体系 调用socket()返回的。
第二个参数是serv_addr是指向数据布局 sockaddr的指针,此中 包括目的 端口和IP地址。
第三个参数可以使用 sizeof(structsockaddr)而获得。
下面是一个例子:

  1. #include<string.h>
  2. #include<sys/types.h>
  3. #include<sys/socket.h>
  4. #define DEST_IP "132.241.5.10"
  5. #define DEST_PORT 23
  6. main()
  7. {
  8. int sockfd;
  9. struct sockaddr_in dest_addr; /*will hold the destination addr*/
  10. sockfd=socket(AF_INET, SOCK_STREAM, 0); /*do some error checking!*/
  11. dest_addr.sin_family=AF_INET; /*hostbyteorder*/
  12. dest_addr.sin_port=htons(DEST_PORT); /*short,network byte order*/
  13. dest_addr.sin_addr.s_addr=inet_addr(DEST_IP);
  14. bzero(&(dest_addr.sin_zero), 8); /*zero the rest of the struct*/
  15. /*don'tforgettoerrorchecktheconnect()!*/
  16. connect(sockfd,(struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
  17. ...
  18. }
复制代码

同样,假如 出错,connect()将会返回-1。
--------------------------------------------------------------------------------

listen()
假如 你盼望 不毗连 到长途 的主机,也就是说你盼望 等待一个进入的毗连 哀求 ,然后再处理它们。如许 ,你通过起首 调用listen(),然后再调用accept()来实现。
体系 调用listen()的情势 如下:
intl isten(int sockfd, int backlog);
第一个参数是体系 调用socket()返回的套接口文件形貌 符。
第二个参数是进入队列中答应 的毗连 的个数。进入的毗连 哀求 在使用 体系 调用accept()应答之前要在进入队列中等待。这个值是队列中最多可以拥有的哀求 的个数。大多数体系 的缺省设置为20。你可以设置为5或者10。当出错时,listen()将会返回-1值。
当然,在使用 体系 调用listen()之前,我们必要 调用bind()绑定到必要 的端口,否则体系 内核将会让我们监听一个随机的端口。以是 ,假如 你盼望 监听一个端口,下面是应该使用 的体系 调用的次序 :
socket();
bind();
listen();
/*accept()goeshere*/
--------------------------------------------------------------------------------

accept()
体系 调用accept()比较起来有点复杂。在长途 的主机大概 试图使用 connect()毗连 你使用
listen()正在监听的端口。但此毗连 将会在队列中等待,直到使用 accept()处理它。调用accept()
之后,将会返回一个全新的套接口文件形貌 符来处理这个单个的毗连 。如许 ,对于同一个毗连
来说,你就有了两个文件形貌 符。原先的一个文件形貌 符正在监听你指定的端口,新的文件描
述符可以用来调用send()和recv()。
调用的例子如下:
#include
intaccept(int sockfd, void *addr, int *addrlen);
第一个参数是正在监听端口的套接口文件形貌 符。第二个参数addr是指向本地的数据布局
sockaddr_in的指针。调用connect()中的信息将存储在这里。通过它你可以相识 哪个主机在哪个
端口呼叫你。第三个参数同样可以使用 sizeof(structsockaddr_in)来获得。
假如 出错,accept()也将返回-1。下面是一个简单的例子:

  1. #include<string.h>
  2. #include<sys/types.h>
  3. #include<sys/socket.h>
  4. #define MYPORT 3490 /*theportuserswillbeconnectingto*/
  5. #define BACKLOG 10 /*howmanypendingconnectionsqueuewillhold*/
  6. main()
  7. {
  8. int sockfd, new_fd; /*listenonsock_fd,newconnectiononnew_fd*/
  9. struct sockaddr_in my_addr; /*myaddressinformation*/
  10. struct sockaddr_in their_addr; /*connector'saddressinformation*/
  11. int sin_size;
  12. sockfd=socket(AF_INET, SOCK_STREAM, 0); /*dosomeerrorchecking!*/
  13. my_addr.sin_family=AF_INET; /*hostbyteorder*/
  14. my_addr.sin_port=htons(MYPORT); /*short,networkbyteorder*/
  15. my_addr.sin_addr.s_addr=INADDR_ANY; /*auto-fillwithmyIP*/
  16. bzero(&(my_addr.sin_zero),8); /*zerotherestofthestruct*/
  17. /*don'tforgetyourerrorcheckingforthesecalls:*/
  18. bind(sockfd,(struct sockaddr *)&my_addr, sizeof(struct sockaddr));
  19. listen(sockfd,BACKLOG);
  20. sin_size=sizeof(struct sockaddr_in);
  21. new_fd=accept(sockfd,&their_addr,&sin_size);
  22. ...
  23. }
复制代码

下面,我们将可以使用 新创建的套接口文件形貌 符new_fd来调用send()和recv()。
--------------------------------------------------------------------------------

send() 和recv()
体系 调用send()的用法如下:
int send(int sockfd, const void* msg, int len, int flags);
第一个参数是你盼望 给发送数据的套接口文件形貌 符。它可以是你通过socket()体系 调用返回的,也可以是通过accept()体系 调用得到的。
第二个参数是指向你盼望 发送的数据的指针。
第三个参数是数据的字节长度。第四个参数标志设置为0。
下面是一个简单的例子:
char*msg="Beejwashere!";
intlen,bytes_sent;
..
len=strlen(msg);
bytes_sent=send(sockfd, msg, len, 0);
...
体系 调用send()返回现实 发送的字节数,这大概 比你现实 想要发送的字节数少。假如 返回的字节数比要发送的字节数少,你在以后必须发送剩下的数据。当send()出错时,将返回-1。
体系 调用recv()的使用 方法和send()类似 :
int recv(int sockfd, void* buf, int len, unsigned int flags);
第一个参数是要读取的套接口文件形貌 符。
第二个参数是保存读入信息的地址。
第三个参数是缓冲区的最大长度。第四个参数设置为0。
体系 调用recv()返回现实 读取到缓冲区的字节数,假如 出错则返回-1。
如许 使用 上面的体系 调用,你可以通过数据流套接口来发送和担当 信息。
--------------------------------------------------------------------------------

sendto() 和recvfrom()
由于 数据报套接口并不毗连 到长途 的主机上,以是 在发送数据包之前,我们必须起首 给出目的 地址,请看:
int sendto(int sockfd, const void* msg, int len, unsigned int flags,
conststruct sockaddr*to, inttolen);
除了两个参数以外,其他的参数和体系 调用send()时类似 。
参数to是指向包含目的 IP地址和端标语 的数据布局 sockaddr的指针。
参数tolen可以设置为sizeof(structsockaddr)。
体系 调用sendto()返回现实 发送的字节数,假如 出错则返回-1。
体系 调用recvfrom()的使用 方法也和recv()的非常 近似:
int recvfrom(int sockfd, void* buf, int len, unsigned int flags
struct sockaddr* from, int* fromlen);
参数from是指向本地计算机中包含源IP地址和端标语 的数据布局 sockaddr的指针。
参数fromlen设置为sizeof(struct sockaddr)。
体系 调用recvfrom()返回汲取 到的字节数,假如 出错则返回-1。
--------------------------------------------------------------------------------

close() 和shutdown()
你可以使用 close()调用关闭毗连 的套接口文件形貌 符:
close(sockfd);
如许 就不能再对此套接口做任何的读写操作了。
使用 体系 调用shutdown(),可有更多的控制权。它答应 你在某一个方向堵截 通讯 ,或者堵截 两边 的通讯 :
int shutdown(int sockfd, int how);
第一个参数是你盼望 堵截 通讯 的套接口文件形貌 符。第二个参数how值如下:
0—Furtherreceivesaredisallowed
1—Furthersendsaredisallowed
2—Furthersendsandreceivesaredisallowed(likeclose())
shutdown()假如 成功则返回0,假如 失败则返回-1。
--------------------------------------------------------------------------------

getpeername()
这个体系 的调用非常 简单。它将告诉你是谁在毗连 的另一端:
#include
int getpeername(int sockfd, struct sockaddr* addr, int* addrlen);
第一个参数是毗连 的数据流套接口文件形貌 符。
第二个参数是指向包含另一端的信息的数据布局 sockaddr的指针。
第三个参数可以设置为sizeof(structsockaddr)。
假如 出错,体系 调用将返回-1。
一旦你获得了它们的地址,你可以使用 inet_ntoa()或者gethostbyaddr()来得到更多的信息。
--------------------------------------------------------------------------------

gethostname()
体系 调用gethostname()比体系 调用getpeername()还简单。它返回程序正在运行的计算机的名字。体系 调用gethostbyname()可以使用 这个名字来决定你的机器的IP地址。
下面是一个例子:
#include
int gethostname(char*hostname, size_t size);
假如 成功,gethostname将返回0。假如 失败,它将返回-1。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 紫影蓝星惹 | 2021-9-12 23:10:58 | 显示全部楼层
admin楼主的帖子越来越有深度了!
回复

使用道具 举报

avatar 心一路向南飞该 | 2021-9-17 22:43:07 | 显示全部楼层
看了这么多帖子,第一次看到这么有深度了!
回复

使用道具 举报

avatar 哈哈笑417 | 2021-9-19 16:12:31 | 显示全部楼层
灌水不是我的目的!
回复

使用道具 举报

avatar 王枫13898316786 | 2021-10-4 23:29:43 | 显示全部楼层
楼上的这是啥态度呢?
回复

使用道具 举报

admin楼主会死的很有节奏的!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则