使用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. jdbc 事物

    package transaction; import jdbc.utils.*; import java.sql.Connection; import java.sql.PreparedStatem ...

  2. Kubernetes 健康检查的两种机制:Liveness 探测和 Readiness 探测

    Kubernetes 健康检查的两种机制:Liveness 探测和 Readiness 探测,并实践了健康检查在 Scale Up 和 Rolling Update 场景中的应用.kubelet使用启 ...

  3. SQL语句之-计算字段/分组

    五.计算字段 1.拼接字段 MySQL:使用函数concat SqlServer:使用加号+ oracle:使用|| SELECT CONCAT(vend_name,'(',vend_country, ...

  4. express设置允许跨域访问该服务.

    const express = require('express');const app = express(); //设置允许跨域访问该服务.app.all('*', function (req, ...

  5. leetcode上的一些单链表

    147- 思路: 148- 思路: 24- 思路: 25- 思路: 21- 思路: 109- 思路: 237- 思路:

  6. Canal( 增量数据订阅与消费 )的理解及应用

    canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 起源:早期,阿里巴巴B2B公司因为存 ...

  7. php下载

    生成迅雷下载链接 $url = "http://www.xxx.com/xxx/test.jpg"; echo "thunder://".base64_enco ...

  8. 原 Nginx网络架构实战学习笔记(七):nginx性能优化小总结

    文章目录 优化思路: 优化过程 Php-mysql的优化 Nginx+phjp+mysql+nginx 压力测试: 模拟 前0-10万是热数据, 10-20万是冷门数据 请求热数据 0-10,请求9次 ...

  9. OAccflow集成sql

    SELECT * FROM PORT_EMP WHERE NO='18336309966'SELECT * FROM PORT_DEPT WHERE no='42DBAF50712C4046B09BC ...

  10. 64位系统sql链接oracle

    在SQL Server 2008中连接Oracle,完成查询.插入操作 建立指向Oracle的连接 在32位的系统中sql链接oracle,在链接服务器里点击服务器对象,右键链接服务器,选择micro ...