FPGA / ARM / DSP Wishbone SoC
<
WB+LINUX+USB+TCPIP+WEBServer >
Lab3 : TCP/IP Message Transfers
WB+LINUX+USB+TCPIP+WEBServer 整合實驗3
▋Introduction
Lab.3本實驗在ARM9 Linux Kernel上, 應用ARM週邊模組的Ethernet Controller與Linux核心的 protocal stack, 進行以TCP/IP作遠端信息交換應用, 在下一章節,此一信息便作為I/O控制用。
實驗程式以Client/Server的形式, Client端發送一信息, Server端收到後,回應此一信息。
此實驗Server端為ZX Integrator實驗器, Client端為PC,在此例為Ubuntu下是應用程式, 亦可為Windows或Cygwin下的應用程式。
另外也可以將Client端改成是另一個ZX Integrator作為此一Client, 或是對稱的Peer to Peer形式, 但信息輸入方式必須透過USB Keyboard或其他I/O。
▋ Design Codes
simplesvr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define LISTENPORT 7500
#define BACKLOG 10
#define MSG "Hello, how are you?"
int main(int argc, char * argv[]) {
int sock, conn;
struct sockaddr_in my_addr, client_addr;
int sockopt_on = 1;
int sa_in_size = sizeof(struct sockaddr_in);
char response[80];
printf("starting....\n");
//get a socket
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("socket");
exit(1);
}
//make it reusable
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&sockopt_on,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
//first zero the struct
memset((char *) &my_addr, 0, sa_in_size);
//now fill in the fields we need
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons(LISTENPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind our socket to the port
if (bind(sock,(struct sockaddr *)&my_addr, sa_in_size) == -1) {
perror("bind");
exit(1);
}
//start listening for incoming connections
if (listen(sock,BACKLOG) == -1) {
perror("listen");
exit(1);
}
while(1) {
//grab connections
conn = accept(sock, (struct sockaddr *)&client_addr, &sa_in_size);
if (conn == -1) {
perror("accept");
exit(1);
}
//log the connecter
printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));
//send a greeting
if (send(conn,MSG,strlen(MSG)+1,0) == -1) {
perror("send");
}
//get the reply
if (recv(conn, &response, 80, 0) == -1) {
perror("recv");
}
printf("The client says \"%s\"\n",&response);
close(conn);
}
return 0;
}
Makefile
CROSS=/usr/local/arm/3.4.1/bin/arm-linux-
all: simplesvr
simplesvr:
$(CROSS)gcc -o simplesvr simplesvr.c
clean:
rm -rf simplesvr simplesvr.o
simplecln.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 7500
#define BUFLEN 100
#define MSG "Well, thanks for asking."
int main(int argc, char * argv[]) {
int sock;
char buf[BUFLEN];
struct hostent * he;
struct sockaddr_in server_addr;
int bytecount;
if (argc != 2) {
fprintf(stderr,"usage: %s [hostname]\n", argv[0]);
exit(1);
}
//look up the host
he = gethostbyname(argv[1]);
if (he == NULL) {
perror("gethostbyname");
exit(1);
}
//get a socket
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("socket");
exit(1);
}
//set the fields for the server address struct
memset((char *) &server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
//connect to the server
if (connect(sock, (struct sockaddr *) &server_addr,
sizeof(struct sockaddr_in)) == -1) {
perror("connect");
exit(1);
}
//receive the greeting
bytecount = recv(sock,buf,BUFLEN-1, 0);
if (bytecount == -1) {
perror("recv");
exit(1);
}
buf[bytecount] = '\0';
printf("Server says: \"%s\"\n",buf);
//send the reply
if (send(sock,MSG,strlen(MSG)+1,0) == -1) {
perror("send");
exit(1);
}
close(sock);
return 0;
}
Makefile
CRCROSS=/usr/local/arm/3.4.1/bin/arm-linux-
all: simplecln
simplesvr:
# $(CROSS)gcc -o simplesvr simplesvr.c
gcc -o simplecln simplecln.c
clean:
rm -rf simplecln simplecln.o
