首先,看下整个工程文件的结构图:
(1)主文件包含一个Makefile,一起对应的c源文件,还有子文件夹arm_client
(2)子文件夹arm_client
(3)先看一下子文件夹arm_client各个文件的内容:
client.c
/* client.c [root@FriendlyARM /home]# ./client Response from server: TCP TRANSPORTATION TEST! */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include "../wrap.h" #define MAXLINE 80 #define SERV_PORT 8888 int main(int argc, char *argv[]) { struct sockaddr_in servaddr; char buf[MAXLINE]; int sockfd, n; char *str="TCP transportation test!"; sockfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, "192.168.1.108", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); Write(sockfd, str, strlen(str)); n = Read(sockfd, buf, MAXLINE); printf("Response from server:\n"); Write(STDOUT_FILENO, buf, n); printf("\n"); Close(sockfd); return 0; }
CC = gcc ARMCC = arm-linux-gcc OTHER_HEADER = ../wrap.h OTHER_SOURCE = ../wrap.c all: client client: client.c arm_wrap.o $(ARMCC) -o $@ client.c arm_wrap.o arm_wrap.o: $(OTHER_SOURCE) $(OTHER_HEADER) $(ARMCC) -c -o $@ $(OTHER_SOURCE) clean: rm -f *.a *.o server client *~说明:
http://blog.csdn.net/mashang123456789/article/details/9904561
(4)主文件各文件的内容
wrap.h
#ifndef _WRAP_H #define _WRAP_H /* #include <termios.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <pthread.h> #include <string.h> #include <ctype.h> */ #include <stdlib.h> #include <errno.h> #include <sys/socket.h> void perr_exit(const char *s); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); void Bind(int fd, const struct sockaddr *sa, socklen_t salen); void Connect(int fd, const struct sockaddr *sa, socklen_t salen); void Listen(int fd, int backlog); int Socket(int family, int type, int protocol); ssize_t Read(int fd, void *ptr, size_t nbytes); ssize_t Write(int fd, const void *ptr, size_t nbytes); void Close(int fd); ssize_t Readn(int fd, void *vptr, size_t n); ssize_t Writen(int fd, const void *vptr, size_t n); static ssize_t my_read(int fd, char *ptr); ssize_t Readline(int fd, void *vptr, size_t maxlen); #endif
/* #include <stdlib.h> #include <errno.h> #include <sys/socket.h> */ #include "wrap.h" void perr_exit(const char *s) { perror(s); exit(1); } int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) { int n; again: if ( (n = accept(fd, sa, salenptr)) < 0) { if ((errno == ECONNABORTED) || (errno == EINTR)) goto again; else perr_exit("accept error"); } return n; } void Bind(int fd, const struct sockaddr *sa, socklen_t salen) { if (bind(fd, sa, salen) < 0) perr_exit("bind error"); } void Connect(int fd, const struct sockaddr *sa, socklen_t salen) { if (connect(fd, sa, salen) < 0) perr_exit("connect error"); } void Listen(int fd, int backlog) { if (listen(fd, backlog) < 0) perr_exit("listen error"); } int Socket(int family, int type, int protocol) { int n; if ( (n = socket(family, type, protocol)) < 0) perr_exit("socket error"); return n; } ssize_t Read(int fd, void *ptr, size_t nbytes) { ssize_t n; again: if ( (n = read(fd, ptr, nbytes)) == -1) { if (errno == EINTR) goto again; else return -1; } return n; } ssize_t Write(int fd, const void *ptr, size_t nbytes) { ssize_t n; again: if ( (n = write(fd, ptr, nbytes)) == -1) { if (errno == EINTR) goto again; else return -1; } return n; } void Close(int fd) { if (close(fd) == -1) perr_exit("close error"); } ssize_t Readn(int fd, void *vptr, size_t n) { size_t nleft; ssize_t nread; char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { if ( (nread = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) nread = 0; else return -1; } else if (nread == 0) break; nleft -= nread; ptr += nread; } return n - nleft; } ssize_t Writen(int fd, const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { if ( (nwritten = write(fd, ptr, nleft)) <= 0) { if (nwritten < 0 && errno == EINTR) nwritten = 0; else return -1; } nleft -= nwritten; ptr += nwritten; } return n; } static ssize_t my_read(int fd, char *ptr) { static int read_cnt; static char *read_ptr; static char read_buf[100]; if (read_cnt <= 0) { again: if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { if (errno == EINTR) goto again; return -1; } else if (read_cnt == 0) return 0; read_ptr = read_buf; } read_cnt--; *ptr = *read_ptr++; return 1; } ssize_t Readline(int fd, void *vptr, size_t maxlen) { ssize_t n, rc; char c, *ptr; ptr = vptr; for (n = 1; n < maxlen; n++) { if ( (rc = my_read(fd, &c)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { *ptr = 0; return n - 1; } else return -1; } *ptr = 0; return n; }以上两个文件被编译的两次,在子文件里面被编译成目标文件arm_wrap.o,在主文件里面被编译成wrap.o
server.c
/* server.c bind error: Address already in use 发生这种问题是由于端口被程序绑定而没有释放造成. 可以使用netstat -lp命令查询当前处于连接的程序以及对应的进程信息。 然后用ps pid 察看对应的进程,并使用kill pid 关闭该进程即可。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include "wrap.h" #define MAXLINE 80 #define SERV_PORT 8888 int DEBUG=1; int main(void) { struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd, connfd; char buf[MAXLINE]; char str[INET_ADDRSTRLEN]; int i, n; listenfd = Socket(AF_INET, SOCK_STREAM, 0);//open a network connection(IPV4 ,TCP) if(DEBUG){ int on=1;//允许地址重用,端口可以马上重用 setsockopt(listenfd, SOL_SOCKET,SO_REUSEADDR, &on, sizeof(on) ); } bzero(&servaddr, sizeof(servaddr));//clear the struct servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));//bind servaddr to socket Listen(listenfd, 20);//The maximum of clients who are waiting for connection is 20 printf("Accepting connections ...\n"); while (1) { cliaddr_len = sizeof(cliaddr);//cliaddr_len 是传入传出参数,每次调用accept前重新赋初值 connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); n = Read(connfd, buf, MAXLINE); printf("received from %s at Client PORT %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));//客户端的端口号是自动分配的 printf("Response from client:\n"); Write(STDOUT_FILENO, buf, n); printf("\n"); for (i = 0; i < n; i++){ //printf("%x",buf[i]);// if add this ,bind error buf[i] = toupper(buf[i]);//把收到的字符转换成大写字母发回去 } Write(connfd, buf, n); Close(connfd); } }
CC = gcc ARMCC = arm-linux-gcc all: server client client: wrap.h make -C arm_client/ all CC=$(ARMCC) cp arm_client/client . server: server.c wrap.o $(CC) -o server server.c wrap.o wrap.o: wrap.c wrap.h $(CC) -c -o $@ wrap.c clean: make -C arm_client/ $@ rm -f *.a *.o server client *~这个Makefile文件做两件事:
第一:生成能在X86上运行的server可执行文件
第二:生成能在ARM上运行的client可执行文件,并吧client从arm_client文件里面复制到当前文件夹