Linux Socket 函数库是从 Berkeley 大学开发的 BSD UNIX 系统中移植过来的。BSD Socket 接口是在众多 Unix 系统中被广泛支持的 TCP/IP 通信接口,Linux 下的 Socket 程序设计,除了微小的差别之外,也适用于大多数其它 Unix 系统。

  Socket 的使用,和文件操作比较类似。如同文件的读、写、打开、关闭等操作一样,TCP/IP 网络通信同样也有这些操作,不过它使用的接口不是文件描述符或者 FILE*,而是一个称做 Socket 的描述符。类似于文件操作,对于 Socket,也通过读、写、打开、关闭操作来进行网络数据传送。同时,还有一些辅助的函数,如域名/IP 地址查询、Socket 功能设置等。

  这星期的实验是Socket编程实验,我将自己的套在框架下写的代码分享出来。一份是TCP代码,sender向receiver发送"hello",receiver将"hello"原封不动发回去,sender接收到"hello"后断开连接,两个服务同时down。第二份是UDP代码,receiver监听自己的端口,sender向receiver发送0-8的整数,receiver不会对收到了的信息作确认。发送完毕后sender down,receiver会继续监听。

  阅读接下来的代码需要对Socket中的函数,Socket标志符等概念十分清楚,其中一份TCP代码经过了详细的注释。bind(),listen(),send()......这些Socket库中的函数都需要读者提前了解他们的功能。

  放出一份TCP Receiver的代码,其余的代码在文末可以下载。

 1 #include <stdio.h>
 2 #include <string.h>
 3 //数据格式转换
 4 #include "net_exp.h"
 5 #include <netinet/in.h>
 6 #define PORT 7000
 7
 8 main(){
 9     //TCP/IP中专用的用于监听连接请求的本地地址
10     struct sockaddr_in client, server;
11     int s,ns,namelen,pktlen;
12     char buf[256];
13     //定义套接字,返回值是Socket描述符
14     s = socket(AF_INET, SOCK_STREAM, 0);
15     //将指针当前位置后面的sizeof(server)个字节清0
16     memset((char*)&server, 0, sizeof(server));
17     //Address family
18     server.sin_family = AF_INET;
19     //Port number,转换成unsigned short int
20     server.sin_port = htons(TCP_SERVER_PORT);
21     server.sin_addr.s_addr = INADDR_ANY;
22     //给已经打开的socket指定本地地址,注意看,传参数的时候有类型转换
23     bind(s, (struct sockaddr*)&server, sizeof(server));
24     //s-Socket描述符,backlog-连接请求暂存队列长度,
25     //调用listen系统将给此Socket配备一个连接请求的队列,暂存系统接收到的、申请向此Socket建立连接的请求。
26     listen(s, 1);
27     namelen = sizeof(client);
28     //accept:接受指定Socket上的连接请求,返回一个新的socket标识符,相当于创建了一个新的Socket用于传输数据,
29     //原来的Socket仍用来监听请求。
30     ns = accept(s, (struct sockaddr*)&client, &namelen);
31     for(;;){
32         //接收ns上受到的数据,存入buf
33         pktlen = recv(ns, buf, sizeof(buf), 0);
34         if(pktlen==0)
35             break;
36         printf("Received line:%s\n", buf);
37         //向发送方返回一模一样的数据
38         send(ns, buf, pktlen, 0);
39     }
40     close(ns);
41     close(s);
42 }

  TCP效果如下:

(base) appledeMacBook-Pro-4:Socket apple$ ./tcp_sender

[TCP SENDER] receive echo msg[6 bytes]

hello

(base) appledeMacBook-Pro-4:Socket apple$ ./tcp_receiver

Received line:hello

  

  UDP效果如下:

(base) appledeMacBook-Pro-4:Socket apple$ ./udp_sender

sending data packet with #: 0

sending data packet with #: 1

sending data packet with #: 2

sending data packet with #: 3

sending data packet with #: 4

sending data packet with #: 5

sending data packet with #: 6

sending data packet with #: 7

sending data packet with #: 8

(base) appledeMacBook-Pro-4:Socket apple$ ./udp_receiver

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 0.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 1.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 2.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 3.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 4.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 5.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 6.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 7.

[UDP_RECEIVER] receive msg[23 bytes]

data packet with #: 8.

  想自己修改功能编译的话,按照我最近写的一个随笔编译即可。

  

12-28 14:16