linux网络编程

什么是socket

socket的中文是套接字,在网络编程中,套接字就像是网络世界的通信端口,应用程序能通过这个端口来传递数据。

套接字的工作原理

套接字的工作原理就像是电话通话的过程。首先,你需要拨打一个号码(即IP地址+端口号)来建立连接。一旦连接建立,电话线(网络连接)就激活了,你的声音(数据)就可以通过它传送。

在这个过程中:

  1. 拨号对应于网络编程中的连接建立,这是通过调用套接字API来完成的,比如 connect( )函数。
  2. 通话对应于数据传输,你可以通过套接字发送 send( ) 和接收 recv( )数据。
  3. 挂断对应于结束连接,完成通信后,你需要关闭套接字 close( )函数,以结束会话并清理资源。

在整个通信过程中,套接字保证了数据从一个程序准确地传送到另一个程序,无论这两个程序是在同一台计算机上还是跨越了广阔的互联网。

在 Linux 中,套接字其实就是一系列的编程接口,Linux 提供了很多特定的API来创建和使用套接字,接下来,让我们学习如何使用 Linux 套接字 api 来编写各种网络服务程序。

TCP套接字

服务端

这里写一个示例,不作具体说明。

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
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char **argv)
{
int i_socketserver;
int i_socketclient;
int len;
struct sockaddr_in isockaddr;
struct sockaddr_in client_addr;
unsigned char buf[100];

i_socketserver = socket(AF_INET, SOCK_STREAM, 0);

memset(&isockaddr, 0, sizeof(isockaddr));
isockaddr.sin_family = AF_INET;
isockaddr.sin_port = htons(8888);
isockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(bind(i_socketserver, (const struct sockaddr*)&isockaddr, sizeof(struct sockaddr)) == -1)
{
printf("bind error\n");
}

if(listen(i_socketserver, 8) == -1)
{
printf("listen error\n");
}

while (1)
{
len = sizeof(struct sockaddr);
i_socketclient = accept(i_socketserver, (struct sockaddr*)&client_addr, (socklen_t *)&len);

if(i_socketclient != -1)
{
printf("conncet: %s\n", inet_ntoa(client_addr.sin_addr));
}

read(i_socketclient, buf, sizeof(buf));
printf("recv: %s\n", buf);
write(i_socketclient, "hello client\n", 13);

}
}

客户端

示例:

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
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>


int main(int argc, char **argv)
{
int i_socketclient;
struct sockaddr_in i_socketclient_addr;
int connect_fd;
unsigned char buf[100];

i_socketclient = socket(AF_INET, SOCK_STREAM, 0);

memset(&i_socketclient_addr, 0, sizeof(i_socketclient_addr));
i_socketclient_addr.sin_family = AF_INET;
i_socketclient_addr.sin_port = htons(8888);
i_socketclient_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(connect(i_socketclient, (const struct sockaddr *)&i_socketclient_addr, sizeof(struct sockaddr)) == -1)
{
printf("connect error\n");
}
else
{
printf("OK\n");
}

write(i_socketclient, "hello server\n", 13);
read(i_socketclient, buf, sizeof(buf));
printf("recv: %s\n", buf);

while (1)
{

}
}