linux键盘套接字大全,Linux_套接字编程

面向无连接的套接字通信流程:

服务器:socket(), bind(), recvfrom(), sendto();

客户端:socket(), bind(), sendto(), recvfrom();

面向连接的套接字通信流程:

服务器:socket(), bind(), listen(),

accept(), read(), write();

客户端:socket(), connect(), write(),

read();

系统函数:

#include

#include

int socket(int domain, int type, int protocol);

作用:创建套接字。

参数:domain表示通信使用的协议族,有如下值:

AF_UNIX, AF_LOCAL Local communication

AF_INET IPv4 Internet protocols

AF_INET6 IPv6 Internet protocols

AF_IPX IPX - Novell protocols

AF_NETLINK Kernel user interface device

AF_X25 ITU-T X.25 / ISO-8208 protocol

AF_AX25 Amateur radio AX.25 protocol

AF_ATMPVC Access to raw ATM PVCs

AF_APPLETALK Appletalk

AF_PACKET Low level packet interface

type表示套接字类型,有如下值:

SOCK_STREAM

SOCK_DGRAM

SOCK_SEQPACKET

SOCK_RAW

SOCK_RDM

SOCK_PACKET

SOCK_NONBLOCK

SOCK_CLOEXEC

protocol表示套接字通信时使用的一个特定协议,通常设置为0。

返回值:文件描述符表示一个新创建的套接字。-1表示失败。errno将被系统设置标明具体的错误。

库函数:

#include

int socket(int domain, int type, int protocol);

作用,参数,返回值同系统函数的int

socket(...);

系统函数:

#include

#include

int setsockopt(int sockfd, int level, int

optname, const void *optval, socklen_t optlen);

作用:设置某个套接字选项的值。

参数:sockfd表示需要设置哪个套接字选项的值。level表示该选项在哪个协议层,通常设置为SOL_SOCKET。optname表示需要设置哪个选项,有如下值:

SO_DEBUG

SO_BROADCAST

SO_REUSEADDR

SO_KEEPALIVE

SO_LINGER

SO_OOBINLINE

SO_SNDBUF

SO_RCVBUF

SO_DONTROUTE

SO_RCVLOWAT

SO_RCVTIMEO

SO_SNDLOWAT

SO_SNDTIMEO

optval表示设置的值由该指针指向。optlen表示设置的值的长度。

返回值:0表示设置成功。-1表示失败。errno将被系统设置标明具体的错误。

库函数:

#include

int setsockopt(int socket, int level, int option_name, const

void *option_value, socklen_t option_len);

作用,参数,返回值同系统函数的intsetsockopt(...);

系统函数:

#include

#include

int getsockopt(int sockfd, int level, int optname, void

*optval, socklen_t *optlen);

作用:获取某个套接字选项的值。

参数:同系统函数的int setsockopt();

返回值:0表示获取成功。-1表示失败。errno将被系统设置标明具体的错误。

库函数:

#include

int getsockopt(int socket, int level, int option_name, void

*restrict option_value, socklen_t *restrict option_len);

作用,参数,返回值同系统函数的int

getsockopt(...);但有更多的选项可以获取,有如下值:

SO_ACCEPTCONN

SO_ERROR

SO_TYPE

系统函数:

#include

#include

ssize_t send(int sockfd, const void *buf, size_t len, int

flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int

flags, const struct sockaddr *dest_addr, socklen_t addrlen);

作用:发送消息到另一个套接字。

参数:sockfd表示源套接字的fd。buf表示要发送的消息。len表示消息的长度。flags可以使用或操作设置为如下值:

MSG_CONFIRM (Since Linux 2.3.15)

MSG_DONTROUTE

MSG_DONTWAIT (since Linux 2.2)

MSG_EOR (since Linux 2.2)

MSG_MORE (Since Linux 2.4.4)

MSG_NOSIGNAL (since Linux 2.2)

MSG_OOB

dest_addr和addrlen的设置情况如下:

If sendto() is used on a connection-mode (SOCK_STREAM,

SOCK_SEQPACKET) socket, the arguments dest_addr and addrlen are

ignored (and the error EISCONN may be returned when they are not

NULL and 0), and the error ENOTCONN is returned when the socket was

not actually connected. Otherwise, the address of the target is

given by dest_addr with addrlen specifying its size.

返回值:实际发送的字符个数。-1表示发送失败。errno将被系统设置标明具体的错误。

额外说明:也可以使用ssize_t write(int fd, const void *buf, size_t

count);将数据写入到套接字中,相当于sendto()

库函数:

#include

ssize_t send(int socket, const void *buffer, size_t length,

int flags);

ssize_t sendto(int socket, const void *message, size_t length,

int flags, const struct sockaddr *dest_addr, socklen_t

dest_len);

作用,参数,返回值同系统函数的ssize_t sendto(...);但参数flags仅可以设置为如下值:

MSG_EOR

MSG_OOB

系统函数:

#include

#include

ssize_t recv(int sockfd, void *buf, size_t len, int

flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

struct sockaddr *src_addr, socklen_t *addrlen);

作用:从一个套接字接收消息。

参数:sockfd表示接收套接字的fd。buf表示将接收到的数据放在哪(通常是数组)。len表示buf的长度。flags的值如下:

MSG_CMSG_CLOEXEC (recvmsg() only; since Linux 2.6.23)

MSG_DONTWAIT (since Linux 2.2)

MSG_ERRQUEUE (since Linux 2.2)

MSG_OOB

MSG_PEEK

MSG_TRUNC (since Linux 2.2)

MSG_WAITALL (since Linux 2.2)

MSG_EOR

MSG_TRUNC

MSG_CTRUNC

MSG_OOB

MSG_ERRQUEUE

flagssrc_addr和addrlen的设置如下:

Ifsrc_addris

not NULL, and the underlying protocol provides the source address,

this source address is filled in.

Whensrc_addris

NULL, nothing is filled in; in this

case,addrlenis

not used, and should also be NULL. The

argumentaddrlenis

a value-result argument, which the caller should initialize before

the call to the size of the buffer associated

withsrc_addr,

and modified on return to indicate the actual size of the source

address. The returned address is truncated if the buffer provided

is too small; in this case,addrlenwill

return a value greater than was supplied to the call.

返回值:实际接收到的字节数。-1表示失败。If no messages are available to be received

and the peer has performed an orderly shutdown, recvfrom() shall

return 0.errno将被系统设置标明具体的错误。

额外说明:也可以使用ssize_t read(int fd, void *buf, size_t

count);将从套接字中读取数据,相当于recvfrom()

库函数:

#include

ssize_t recv(int socket, void *buffer, size_t

length, int flags);

ssize_t recvfrom(int socket, void *restrict buffer, size_t

length, int flags, struct sockaddr *restrict address, socklen_t

*restrict address_len);

作用,参数,返回值同系统函数的ssize_t recvfrom(...);但参数flags仅可以设置为如下值:

MSG_PEEK

MSG_OOB

MSG_WAITALL

系统函数:

#include

#include

int bind(int sockfd, const struct sockaddr *addr, socklen_t

addrlen);

作用:将套接字与IP地址/端口号绑定。

参数:sockfd表示需要绑定的套接字。addr表示指向sockaddr结构体的指针。addrlen表示sockaddr的长度。

struct sockaddr {

sa_family_t

sa_family;

char  sa_data[14];

}

返回值:0表示绑定成功。-1表示失败。errno将被系统设置标明具体的错误。

库函数:

#include

int bind(int socket, const struct sockaddr *address, socklen_t

address_len);

作用,参数,返回值同系统函数的int

bind(...);

系统函数:

#include

#include

int listen(int sockfd, int backlog);

作用:设置套接字接口的监听状态。

参数:sockfd表示需要设置监听状态的套接字。backlog表示能够处理的最大的客户端连接数。

返回值:0表示监听状态设置成功。-1表示失败。errno将被系统设置标明具体的错误。

库函数:

#include

int listen(int socket, int backlog);

作用,参数,返回值同系统函数的int

listen(...);

系统函数:

#include

#include

int accept(int sockfd, struct sockaddr *addr, socklen_t

*addrlen);

作用:接受客户端的连接请求。

参数:sockfd表示监听客户端连接请求的套接字。addr表示指向sockaddr结构体的指针。addrlen表示sockaddr的长度。

struct sockaddr {

sa_family_t

sa_family;

char  sa_data[14];

}

返回值:一个非负整数表示用于数据传输的文件描述符。-1表示失败。errno将被系统设置标明具体的错误。

额外说明:函数执行到accept()函数时,会hang住,等待客户端的连接,这时可以通过开启一个新的终端,输入netstat -an

| grep

来查看服务器的状态。之后输入telnet

(相当于一个连接请求)来查看服务器的accept()函数的执行效果。之后输入test send content aaaaaaa

(相当于发送一个字符串)来查看服务器的read()或recvfrom()等函数的执行效果。

库函数:

#include

int accept(int socket, struct sockaddr *restrict address,

socklen_t *restrict address_len);

作用,参数,返回值同系统函数的int

accept(...);

额外说明:Theaccept()

function shall extract the first connection on the queue of pending

connections, create a new socket with the same socket type protocol

and address family as the specified socket, and allocate a new file

descriptor for that socket.

系统函数:

#include

#include

int connect(int sockfd, const struct sockaddr *addr, socklen_t

addrlen);

作用:在客户端的套接字上发送连接请求。

参数:sockfd表示发送连接请求的客户端套接字。addr表示指向sockaddr结构体的指针,sockaddr中存储着服务器的IP地址和端口信息。addrlen表示sockaddr的长度。

struct sockaddr {

sa_family_t

sa_family;

char  sa_data[14];

}

返回值:0表示连接成功。-1表示失败。errno将被系统设置标明具体的错误。

库函数;

#include

int connect(int socket, const struct sockaddr *address,

socklen_t address_len);

作用,参数,返回值同系统函数的int

connect(...);

客户端代码:

#include

#include

#include

#include

#include

#include

#include

const char *const socket_name = “my_socket”;

const char *const cmd_edload_test = "edload";

int socket_fd;

struct sockaddr_un serv_addr;

int pass = 0;

int fail = 0;

int open_socket()

{

socket_fd =

socket(AF_LOCAL, SOCK_STREAM, 0);

if

(socket_fd < 0) {

LOGE("Failed to create socket: %s", strerror(errno));

return RET_FAILED;

}

memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sun_family = AF_LOCAL;

//snprintf(serv_addr.sun_path, UNIX_PATH_MAX, "%s",

socket_name);

snprintf(serv_addr.sun_path, 108, "%s", socket_name);

serv_addr.sun_path[0] = 0;

return

RET_SUCCESS;

}

int connect_socket()

{

if

(connect(socket_fd, (struct sockaddr*)

&serv_addr,

offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) != 0)

{

LOGE("Failed to connect to socket: %s", strerror(errno));

close(socket_fd);

return RET_FAILED;

}

return

RET_SUCCESS;

}

int write_data()

{

int

bytes_written;

bytes_written = write(socket_fd, cmd_edload_test,

strlen(cmd_edload_test));

if

(bytes_written < 0) {

LOGE("Failed to write data to socket :%s:", strerror(errno));

close (socket_fd);

return RET_FAILED;

}

return

RET_SUCCESS;

}

int read_data()

{

int

status;

int

bytes_read;

int offset =

0;

do {

bytes_read = read(socket_fd, &status,

sizeof(status) - offset);

if (bytes_read < 0

&& errno != EAGAIN) {

LOGE("Failed to read data from socket: %s", strerror(errno));

return RET_FAILED;

}

offset += bytes_read;

} while

(bytes_read > 0 &&

offset < sizeof(int));

LOGI("Return

status is %d", status);

if (status

== RET_SUCCESS) {

pass ++;

return RET_SUCCESS;

}

LOGE("Failed

to read expected status");

fail

++;

return

RET_FAILED;

}

int close_socket()

{

if

(close(socket_fd) != 0) {

LOGE("Failed to close socket: %s", strerror(errno));

return RET_FAILED;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值