套接字2

socket套接字(2)

socket编程基本函数

socket编程的基本函数有socket()、bind()、listen()、accept()、send()、sendto()、recv()以及recvfrom()等,函数说明如下:

  • socket() :该函数用于建立一个socket连接,可指定socket类型等信息。在建立了socket连接后,可对sockaddr或sockaddr_in结构体进行初始化,以保存所建立的socket地址信息
  • bind():该函数是用于将本地IP地址绑定到端口号,若绑定其他IP地址则不成成功,主要用于TCP的连接
  • listen():在服务端程序建立套接字和地址绑定之后,还需要准备在该套接字上接收新的连接请求。此时调用listen()函数来创建一个等待队列,在其中存放未处理的客户端连接请求
  • accept():服务端程序调用listen()函数创建等待队列之后,调用accept()函数等待并接收客户端的连接请求。它通常在bind()所创建的等待队列中取出第一个未处理的连接请求
  • send()和recv():分别用于发送和接收数据
  • sendto()和recvfrom():和send()和recv()类似,UDP时可以用在没有使用connect()的情况

socket编程流程

TCP协议

tcp

UDP协议

udp

函数介绍

1
2
3
4
5
6
7
8
#include <sys/socket.h>
int socket (int family, int type, int protocol);
int bind (int sockfd, struct sockaddr *my_addr, int addrlen);
int listen (int sockfd, int backlog);
int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
int send (int sockfd, const void *msg, int len, int flags);
int recv (int sockfd, void *buff, int len, unsigned int flags);

示例

service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define PORT 4321
#define BUFF_SIZE 1024
#define MAX_QUE_CONN_NM 5

int main()
{
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, recvbytes;
int sockfd, client_fd;
char buf[BUFF_SIZE];

/*建立socket连接*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
printf ("socket fd = %d\n", sockfd);

server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
memset(&(server_sockaddr.sin_zero), 0, 8);

int i = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i));
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof (struct sockaddr)) == -1)
{
perror ("bind");
exit (1);
}
printf ("Bind success!\n");

if (listen (sockfd, MAX_QUE_CONN_NM) == -1)
{
perror ("listen");
exit (1);
}
printf ("Listening.....\n");

if ((client_fd = accept (sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
{
perror ("accept");
exit (1);
}

memset (buf, 0, sizeof(buf));
if ((recvbytes = recv (client_fd, buf, BUFF_SIZE, 0)) == -1)
{
perror ("recv");
exit (1);
}
printf ("Recv : %s\n", buf);
close (sockfd);
exit(0);
}

client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

#define PORT 4321
#define BUFF_SIZE 1024

int main(int argc, char *argv[])
{
int sockfd, sendbytes;
char buf[BUFF_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;

if (argc < 3)
{
fprintf (stderr, "USAGE: ./client Hostname(or ip address) Text\n");
exit (1);
}

if ((host = gethostbyname(argv[1])) == NULL)
{
perror ("gethostbyname");
exit (1);
}

memset (buf, 0, sizeof (buf));
sprintf (buf, "%s", argv[2]);

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket");
exit (1);
}
printf ("socket fd = %d\n", sockfd);

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(serv_addr.sin_zero), 0, 8);

if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof (struct sockaddr)) == -1)
{
perror ("connect");
exit (1);
}
printf ("connect success!\n");

if ((sendbytes = send (sockfd, buf, BUFF_SIZE, 0)) == -1)
{
perror ("send");
exit (1);
}
//printf ("Send : %s\n", buf);
close (sockfd);
exit(0);
}


套接字2
https://carl-5535.github.io/2021/06/30/Linux系统编程/套接字2/
作者
Carl Chen
发布于
2021年6月30日
许可协议