linux下socket编程记录

最近要做一个linux下的socket程序用于测试网络连接,基于TCP,我做的是一个放到嵌入式设备里的客户端,向windows服务器发送消息。一路跌跌撞撞走来还没到头,现在把期间遇到的问题记录下来以便查阅。为了方便我用了虚拟机编译程序,windows下编写程序,然后通过共享windows下的源文件到linux下编译,但是在linux下直接编译挂载的源程序时提示出错/usr/bin/ld:cannot open output file client:permision denied collect2:ld 返回1.至今未解决,还望知道的人指点一二。现在只能改完程序后从mnt挂载文件夹下把源程序文件夹拖到linux系统里面再编译。用了select避免阻塞模式,等待时间设置为1秒,但是问题出来了,第一次发送确实延时了1秒,但是后面就没有延时了,原来是忘了把延时参数放置到循环中去,造成只延时一次的后果。目前的我写出来的代码很糟糕,但是我一直在改善,希望能尽快到达自己看起来很舒服的境界,上次代码太长了占据了很大位置,这次改成全部折叠了。林锐说过判断变量是否等于一个值时应该把变量放后面,这说的太对了,1==var是不是比var==1更安全呢,如果写成var=1是不会报错的,但是这并不是想要的结果。写成1=var肯定会报错,这样查找起来也不会无头绪了。还有就是调用带有返回值的函数时应该尽量利用返回值,丰富的返回值是解决问题的良药,想bind,recv,socket这样的函数的返回值很丰富,打印出错信息是个很好的习惯,出错的话找起问题来会更有效率。下面是代码:

View Code
  1 /*
2 *TCP服务器
3 *启动格式:./server 监听端口
4 *功 能:接受远程客户端的连接
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <errno.h>
14 #include <unistd.h>
15 #include <time.h>
16
17 #define INDEX 20*1024 // 缓冲大小
18
19 static int status;
20
21 /************************************************
22 *功 能:创建套接字,监听端口
23 *参 数:监听端口
24 *返回值:创建成功的套接字
25 ************************************************/
26 int CreateSocket(int port)
27 {
28 int sockfd, sockcon;
29 struct sockaddr_in addr_serv, addr_clnt;
30 int on = 1;
31 static int addr_len = sizeof(struct sockaddr_in);
32 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
33 {
34 printf("Create socket failed: %s\n", strerror(errno));
35 exit(1);
36 }
37 printf("Create socket succeed\n");
38
39 status = setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
40 if (-1 == status)
41 {
42 printf("Setsockopt failed: %s\n", strerror(errno));
43 exit(1);
44 }
45
46 /*创建地址结构*/
47 bzero(&addr_serv, addr_len);
48 addr_serv.sin_family = AF_INET;
49 addr_serv.sin_port = htons(port);
50 addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
51
52 /*绑定端口*/
53 status = bind(sockfd, (struct sockaddr *)&addr_serv, sizeof(addr_serv));
54 if (-1 == status)
55 {
56 printf("Bind failed: %s\n", strerror(errno));
57 exit(1);
58 }
59
60 /*监听端口*/
61 listen(sockfd, 5);
62 sockcon = accept(sockfd, (struct sockaddr*)&addr_clnt, &addr_len);
63 return sockcon;
64 }
65
66 /**************************************************
67 *功 能:接收对方的消息
68 *参 数:连接的套接字,接收缓冲区,延时秒数,延时微秒数
69 *返回值:无
70 *格 式:./server 5555
71 **************************************************/
72 void RecvTcp(int sock, char buf[INDEX], int sec, int usec)
73 {
74 time_t tmptime;
75 struct tm *p;
76 int retval, maxfd = -1;
77 struct timeval wait_time;
78 fd_set rfds;
79
80 while (1)
81 {
82 FD_ZERO(&rfds);
83 FD_SET(0, &rfds);
84 maxfd = 0;
85 FD_SET(sock, &rfds);
86 if (sock > maxfd)
87 maxfd = sock;
88 /*最大等待时间*/
89 wait_time.tv_sec = sec;
90 wait_time.tv_usec = usec;
91 //retval = select(maxfd+1, &rfds, NULL, NULL, &wait_time);
92 retval = select(maxfd+1, &rfds, NULL, NULL, NULL);
93 if (-1 == retval) //无操作
94 {
95 printf("No operation: %s\n", strerror(errno));
96 break;
97 }
98 else
99 if (0 == retval) //等待超时,关闭套接字并退出循环
100 {
101 printf("Wait timeout, socket will be closed soon\n");
102 close(sock);
103 break;
104 }
105 else //有操作
106 {
107 if (FD_ISSET(sock, &rfds)) //收到了消息
108 {
109 time(&tmptime);
110 p = localtime(&tmptime);
111 bzero(buf, INDEX);
112 status = recv(sock, buf, INDEX, 0);
113
114 if (-1 == status)
115 {
116 printf("Receive failed: %s\n", strerror(errno));
117 close(sock);
118 break;
119 }
120 else
121 if (0 == status)
122 {
123 printf("Disconnect to client\n");
124 close(sock);
125 break;
126 }
127 else
128 {
129 printf("lihuoliang-client %d:%d:%d\n>>", p->tm_hour, p->tm_min, p->tm_sec);
130 //write(STDOUT_FILENO, buf, status);
131 printf("%s\n", buf);
132 }
133 }
134 if (FD_ISSET(0, &rfds)) //有键按下
135 {
136 bzero(buf, INDEX);
137 status = read(STDIN_FILENO, buf, INDEX);
138 if (status < 0)
139 {
140 printf("Read failed: %s\n", strerror(errno));
141 exit(1);
142 }
143 status = send(sock, buf, strlen(buf), 0);
144 if (-1 == status)
145 {
146 printf("Send failed: %s\n", strerror(errno));
147 }
148 }
149 }
150 }
151 }
152
153 /****************************************
154 *功 能:main
155 *参 数:无
156 *返回值:无
157 *****************************************/
158 main(int argc, char **argv)
159 {
160 int sockcon;
161 char recvbuf[INDEX] = {0};
162 if (argc < 2)
163 {
164 printf("Too few arguments for main\n");
165 }
166 sockcon = CreateSocket(atoi(argv[1]));
167 printf("pid=%d\n", getpid());
168 RecvTcp(sockcon, recvbuf, 2, 0);
169
170 return 0;
171 }
View Code
  1 /*
2 *TCP客户端
3 *启动格式: ./client 远程地址 远程端口
4 *功 能: 连接远程服务器
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <errno.h>
16 #include <time.h>
17
18 #define INDEX 20*1024
19
20 static int sockfd;
21
22 /***********************************************
23 *功 能:创建套接字,连接服务器
24 *参 数:要连接的ip地址,要连接的端口
25 *返回值:无
26 ************************************************/
27 void CreateSocket(char ip_address[16], int port)
28 {
29 struct sockaddr_in addr_serv;
30 int addr_len = sizeof(struct sockaddr_in);
31 /* 创建套接字 */
32 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
33 {
34 printf("Create socket failed: %s\n", strerror(errno));
35 exit(1);
36 }
37
38 /* 创建地址结构 */
39 bzero(&addr_serv, addr_len);
40 addr_serv.sin_family = AF_INET;
41 addr_serv.sin_port = htons(port);
42 addr_serv.sin_addr.s_addr = inet_addr(ip_address);
43
44 if (connect(sockfd, (struct sockaddr*)&addr_serv, addr_len) < 0)
45 {
46 printf("Connect failed: %s\n", strerror(errno));
47 exit(1);
48 }
49 printf("Connect success!\n");
50 }
51
52 /********************************************************
53 *功 能:发送消息给对方
54 *参 数:连接的套接字,发送缓冲区,延时秒数,延时微秒数
55 *返回值:无
56 *********************************************************/
57 void SendTcp(int sock, char buf[INDEX], int sec, int usec)
58 {
59 time_t tmptime;
60 struct tm *p;
61 int status;
62 struct timeval wait_time;
63 fd_set rfds;
64 int retval, maxfd = -1;
65
66 while (1)
67 {
68 FD_ZERO(&rfds);
69 FD_SET(0, &rfds);
70 maxfd = 0;
71 FD_SET(sock, &rfds);
72 if (sock > maxfd)
73 maxfd = sock;
74
75 /*最大等待时间*/
76 wait_time.tv_sec = sec;
77 wait_time.tv_usec = usec;
78
79 retval = select(maxfd+1, &rfds, NULL, NULL, NULL);
80 /*选择操作*/
81 if (-1 == retval) //无操作
82 {
83 printf("No operation: %s\n", strerror(errno));
84 break;
85 }
86 else
87 if (0 == retval) //等待超时,关闭套接字并推出
88 {
89 printf("Wait timeout, socket will be closed soon\n");
90 close(sock);
91 break;
92 }
93 else //有操作
94 {
95 if (FD_ISSET(sock, &rfds)) //收到了消息
96 {
97 time(&tmptime);
98 p = localtime(&tmptime);
99 bzero(buf, INDEX);
100 status = recv(sock, buf, INDEX, 0);
101 if (-1 == status)
102 {
103 printf("Receive failed: %s\n", strerror(errno));
104 close(sock);
105 break;
106 }
107 else
108 if (0 == status)
109 {
110 printf("Disconnect to client\n");
111 close(sock);
112 break;
113 }
114 else
115 {
116 printf("lihuoliang-server %d:%d:%d\n>>", p->tm_hour, p->tm_min, p->tm_sec);
117 //write(STDOUT_FILENO, buf, status);
118 printf("%s\n", buf);
119 }
120 }
121 if (FD_ISSET(0, &rfds)) //有键按下
122 {
123 bzero(buf, INDEX);
124 status = read(STDIN_FILENO, buf, INDEX);
125 if (status < 0)
126 {
127 printf("Read failed: %s\n", strerror(errno));
128 exit(1);
129 }
130 status = send(sock, buf, strlen(buf), 0);
131 if (-1 == status)
132 {
133 printf("Send failed: %s\n", strerror(errno));
134 }
135 }
136 }
137 }
138 }
139
140 /******************************************
141 *功 能:main
142 *参 数:ip地址,端口
143 *返回值:无
144 *格 式:./client 192.168.119.131 5555
145 *******************************************/
146 int main(int argc, char **argv)
147 {
148 char sendbuf[INDEX] = {0};
149 if (argc < 3)
150 {
151 printf("Too few arguments for main\n");
152 }
153
154 CreateSocket(argv[1], atoi(argv[2]));
155 printf("pid=%d\n", getpid());
156 SendTcp(sockfd,sendbuf, 2, 0);
157
158 return 0;
159 }




posted on 2012-01-16 17:36  快跑蜗牛  阅读(358)  评论(0编辑  收藏  举报

导航