使用bind来关联地址和套接字

#include <sys/types.h>
#include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

getsockname函数来发现绑定到套接字上的地址

#include <sys/socket.h>

int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

如果套接字已经和对等方连接,可以调用getpeername函数来找到对方的地址

#include <sys/socket.h>

int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

使用connect函数来建立连接

#include <sys/types.h>
#include <sys/socket.h> int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

服务器调用listen函数来宣告它愿意接收连接请求

#include <sys/types.h>
#include <sys/socket.h> int listen(int sockfd, int backlog);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
backlog:等待连接队列的最大长度

使用accept函数获取连接请求并建立连接

#include <sys/types.h>
#include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功文件(套接字)描述符,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

send和write很像,但是可以指定标志来改变处理传输数据的方式

#include <sys/types.h>
#include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags);
返回值:成功返回发送字节数,出错-
sockfd:socket描述符
len:缓冲区数据长度
flags:调用执行方式

sendto可以在无连接的套接字上指定一个目标地址

#include <sys/types.h>
#include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
返回值:成功发送的字节数,出错-
sockfd:socket描述符
buf:带发送数据缓冲区
len:缓冲区长度
flags:调用方式标志位,一般为0
dest_addr:指向目的套接字地址
addrlen:所指地址长度

可以调用带有msghdr结构的sendmsg来指定多重缓冲区传输数据,这和writev函数很相似

#include <sys/types.h>
#include <sys/socket.h> ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
返回值:成功发送的字节数,出错-
sockfd:socket描述符
msg:信息头结构指针
flags:可选标记参数位,和send或是sendto参数相同

msghdr结构

struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags (unused) */
};

struct msghdr

函数recv和read相似,但是recv可以指定标志来控制如何接收数据

#include <sys/types.h>
#include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
返回值:数据字节长度,若无可用数据或对等方已经按序结束返回0,出错-
sockfd:socket描述符
buf:接收数据缓冲
len:buf的长度
flags:可选标记位

如果发送者已经调用shutdown来结束传输,或者网络协议支持按默认的顺序关闭并且发送端已经关闭,那么当所有的数据接收完毕后,recv会返回0

如果兴趣定位发送者,可以使用recvfrom来得到数据发送者的源地址

#include <sys/types.h>
#include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
返回值:返回数据字节长度,若无可用数据或对等方已经按序结束,返回0,出错-
sockfd:socket描述符
buf:及诶手数据缓冲
len:buf长度
flags:可选标记位
src_addr:如果非空,它将包含数据发送者的套接字端点地址
addrlen:src_addr参数长度

为了将数据送入多个缓冲区,或者想接收辅助数据,可以使用recvmsg

#include <sys/types.h>
#include <sys/socket.h> ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
返回值:返回数据的自及诶长度,若无可用数据或对等方已经按序结束,返回0,出错-
sockfd:socket描述符
msg:信息头结构指针
flags:可选标志位

可以使用setsockopt函数来设置套接字选项

#include <sys/types.h>
#include <sys/socket.h> int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
返回值:成功0,失败-
sockfd:socket描述符
level:标识了选项应用的协议
optname:需要设置的选项
optval:指向存放选项值的缓冲区指针
optlen:optval的长度

可以使用getsockopt函数来查看选项的当前值

#include <sys/types.h>
#include <sys/socket.h> int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
返回值:成功0,失败-
sockfd:socket描述符
level:标识了选项应用的协议
optname:需要设置的选项
optval:指向存放选项值的缓冲区指针
optlen:指向optval缓冲区的长度

TCP例程:

服务器端:

 #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(void)
{
char buf[MAXLINE];
int listenfd = ; listenfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, ); printf("Accepting connections ...\n");
while()
{
struct sockaddr_in cliaddr = {};
socklen_t cliaddr_len = sizeof(cliaddr);
int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); char str[INET_ADDRSTRLEN];
printf("connect from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
while()
{
int count = read(connfd, buf, MAXLINE);
if(count == )
break; write(connfd, buf, count);
}
close(connfd);
printf("closed from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
}
}

server.c

客户端:

 #include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000
#define MESSAGE "hello world" int main(int argc, char *argv[])
{
char buf[MAXLINE]; int sockfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
printf("connected failed");
return ;
} write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE); printf("Response from server: %s\n", buf); close(sockfd);
return ;
}

client.c

linux IPC socket(2)的更多相关文章

  1. Linux IPC socket 广播,组播

    getsockopt()/setsockopt() //获得sockfd指向的socket的属性 int getsockopt(int sockfd, int level, int optname, ...

  2. Linux IPC socket编程基础

    头文件 #include<unistd.h> #include <sys/types.h> #include <sys/socket.h> #include< ...

  3. linux IPC socket(3)server简单写法

    写server的一些流程总结 一.向内核申请一个socket TCP形式 sock_fd = socket(AF_INET, SOCK_STREAM, ); UDP形式 sfd = socket(AF ...

  4. linux IPC socket

    套接字是通讯端点的抽象 创建一个套接字 #include <sys/types.h> #include <sys/socket.h> int socket(int domain ...

  5. Linux IPC实践(1) -- 概述

    进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...

  6. linux系统socket通信编程详解函数

    linux socket编程之TCP与UDP   TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之 ...

  7. linux ipc/its

    linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  8. linux中socket的理解

    对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...

  9. linux 客户端 Socket 非阻塞connect编程

    开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...

随机推荐

  1. 【leetcode】654. Maximum Binary Tree

    题目如下: Given an integer array with no duplicates. A maximum tree building on this array is defined as ...

  2. c++11引入特性

    * 支持类内初始化. class A{ vector<string> strs{"abc", "def"}; };

  3. 测试demo controllerweb.xml

    <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...

  4. Network基础(二):数制转换

    一.数制转换 目标: 1)请将下列数字转换为十进制数: (110010011111)2 .(10110101110)2 2)请将下列十进制数转换为二进制: 156.2608.1043 方案: 使用按权 ...

  5. 使用 nuxt+iview-admin+koa2 开发项目

    公司最近在做的一个项目,依然是采用熟悉的vue开发,数据平台因为其数据量大的特点,采用传统的spa模式,首页加载时间很长,而SSR这种方式对于首屏的加载时间优化显而易见,同时还可以方便的进行SEO.因 ...

  6. String、StringBuuffer、StringBuilder三者的区别

    string String 字符串常量(final修饰,不可被继承,线程不安全),String是常量,当创建之后即不能更改,可以给多个引用共享,在做大量字符串拼接的时候效率低.(可以通过StringB ...

  7. Django的流程如何理解(餐厅点餐举例)

    去饭店(商场)吃饭的步骤: 告诉前台服务员,来一小碗牛肉拉面,菜单上勾上一个牛肉拉面(url) 服务员去拉面窗口,告诉后厨,一碗牛肉拉面),后厨(view)开始准备. 后厨给打杂小弟说,给我一份儿面条 ...

  8. Notepad++ 连接 FTP 实现编辑 Linux文件

    下载并安装插件 github 下载 :https://github.com/ashkulz/NppFTP/releases/ 安装过程 将下载后解压的文件夹中的 NppFTP.dll 文件,拷贝到 n ...

  9. java多线程学习笔记(四)

    上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...

  10. Spring入门,使用Maven进行管理

    一,使用maven创建项目原型 mvn archetype:generate 进入交互模式创建项目原型,根据网速不同,跳出设置选项的时间不定 第一个选项 直接Enter即可,表示使用默认值502,后面 ...