linux下socket编程

Posted Zzz...y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下socket编程相关的知识,希望对你有一定的参考价值。

综合unp前五章,写了一个服务器-客户端程序。

主要功能:客户端从标准输入读入字符串发送到服务器,服务器显示。服务器接受连接后,fork()子进程实现具体操作。

服务器主要过程:

socket()->bind()->listen()->accept()->read()

客户端:

socket()->connect()->write()

测试结果:

(1)新建服务器、客户端

[email protected]virtual-machine:~$ lsof -i
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
server  16423   zy    3u  IPv4 173909      0t0  TCP *:9999 (LISTEN)
client  16425   zy    3u  IPv4 172544      0t0  TCP localhost:44896->localhost:9999 (ESTABLISHED)
server  16426   zy    4u  IPv4 173910      0t0  TCP localhost:9999->localhost:44896 (ESTABLISHED)

server的父进程处于监听状态,子进程和client处于建立连接状态。

(2)传数据,client发送“OFF”表示关闭连接

[email protected]virtual-machine:~/practice/tcp$ ./client 
socket
hello
OFF

[email protected]-virtual-machine:~/practice/tcp$ ./server 
server ip is 0.0.0.0 running on port 9999
connction from 127.0.0.1, port 44896
socket
hello

(3)关闭连接后的端口状态

[email protected]virtual-machine:~$ lsof -i
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
server  16423   zy    3u  IPv4 173909      0t0  TCP *:9999 (LISTEN)

 

服务器代码:

 1 #include <stdio.h>
 2 #include <sys/socket.h>
 3 #include <sys/types.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 #include <stdlib.h>
 9 
10 
11 void foo(struct sockaddr_in addr, int fd) {
12     char buff[1024];
13     char c;
14     int i;
15     int len;
16     inet_ntop(AF_INET, &addr.sin_addr, buff, sizeof(buff));
17     printf("connction from %s, port %d\n", buff, ntohs(addr.sin_port));
18     while(1) {
19         i = 0;
20         c = 0;
21         while (i < 1024 && c != \0) {
22             len = read(fd, (void*)&c, 1);
23             if (len > 0) {
24                 buff[i++] = c;
25             }
26         }
27         buff[i] = \0;
28         if (i > 1) {
29             if (strcmp(buff, "OFF") == 0){
30                 break;
31             }
32             printf("%s\n", buff);
33         }
34         sleep(1);
35     }
36     exit(0);
37 }
38 int main() {
39     pid_t pid;
40     int serverfd, clientfd;
41     struct sockaddr_in serveraddr, clientaddr;
42     socklen_t clientaddr_len;
43     u_short port = 9999;
44     char buff[1024];
45     serverfd = socket(AF_INET, SOCK_STREAM, 0);
46     if (serverfd == -1) {
47         printf("socket error\n");
48         exit(0);
49     }
50     bzero(&serveraddr, sizeof(serveraddr));
51     serveraddr.sin_family = AF_INET;
52     serveraddr.sin_port = htons(port);
53     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
54     if (bind(serverfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) {
55         printf("bind error\n");
56         exit(0);
57     }
58     inet_ntop(AF_INET, &serveraddr.sin_addr, buff, sizeof(buff));
59     printf("server ip is %s running on port %d\n", buff, ntohs(serveraddr.sin_port));
60 
61     if ( listen(serverfd, 1) == -1 ) {
62         printf("listen error\n");
63         exit(0);
64     }
65     while(1) {
66         clientaddr_len = sizeof(clientaddr);
67         clientfd = accept(serverfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
68         if ((pid = fork()) == 0) {
69             close(serverfd);
70             foo(clientaddr, clientfd);
71             close(clientfd);
72             exit(0);
73         }
74         close(clientfd);
75     }
76     close(serverfd);
77     exit(0);
78 }

客户端代码:

 1 #include <stdio.h>
 2 #include <sys/socket.h>
 3 #include <sys/types.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 #include <stdlib.h>
 9 
10 int main() {
11     int clientfd;
12     struct sockaddr_in clientaddr;
13     char buff[1024];
14     int i;
15     clientfd = socket(AF_INET, SOCK_STREAM, 0);
16     if (clientfd == -1) {
17         printf("socket error\n");
18         exit(0);
19     }
20     clientaddr.sin_family = AF_INET;
21     clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
22     clientaddr.sin_port = htons(9999);
23     if (connect(clientfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr)) == -1) {
24         printf("connet error\n");
25         exit(0);
26     }
27     while (1) {
28         gets(buff);
29         i = 0;
30         do{
31             write(clientfd, (void*)&buff[i], 1);
32         } while (buff[i++] != \0);
33         if (strcmp(buff, "OFF") == 0){
34             break;
35         }
36     }
37     close(clientfd);
38     exit(0);
39 }

 

以上是关于linux下socket编程的主要内容,如果未能解决你的问题,请参考以下文章

Python 之 Socket编程(TCP/UDP)

Linux下Socket编程的端口问题( Bind error: Address already in use )

linux 下 socket编程的一个小问题 代码贴出来了 程序编译完全没有问题 就是服务器出不了结果 是recv问题?

Linux下socket编程基本知识

Windows Socket和Linux Socket编程有什么区别

linux打开终端如何启动scala,如何在终端下运行Scala代码片段?