tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
// create socket
int socketServerListen = socket(AF_INET, SOCK_STREAM, 0);
if (socketServerListen < 0) {
perror("socket");
exit(1);
}
struct sockaddr_in serverAddr;
bzero(&serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
// atoi, 不使用atoi会导致connection refused.
serverAddr.sin_port = htons(atoi(argv[2]));
serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
// bind, notice: it use the standard struct: sockaddr, not sockaddr_in
if (bind(socketServerListen, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr)) < 0) {
perror("bind");
exit(2);
}
// listen
if (listen(socketServerListen, 30) < 0) {
perror("listen");
exit(3);
}
struct sockaddr_in clientAddr;
bzero(&clientAddr, sizeof(clientAddr));
int connFd;
// Invalid argument, if not initialized.
// 如果不初始化,在accept中会直接报: Invalid argument.
socklen_t clientAddrLen = 0;
while (1) {
// accpet was different with bind, the parameters 3 was socklen_t*, but not socklen_t.
if (connFd = accept(socketServerListen, (struct sockaddr*)&clientAddr, &clientAddrLen) < 0) {
perror("accept");
continue;
}
printf("tcp_server: client addr is:%s, client port is:%d\n",
inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
pid_t pid = fork();
if (pid < 0) { // error
perror("fork");
} else if (pid == 0) { // child
// in child, it should close the socketServerListen, keep the connFd.
close(socketServerListen);
char buf[1024] = {0};
ssize_t len = 0;
// read the data from the connFd
while (len = read(connFd, buf, 1024) > 0) {
printf("read the data:%s\n", buf);
//write(connFd, buf, len);
}
} else {
// in father, it should close the connFd, just keep the socketServerListen
close(connFd);
}
}
return 0;
}
tcp_client.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
// socket
int clientSockFd = socket(AF_INET, SOCK_STREAM, 0);
if (clientSockFd < 0) {
perror("clientSockFd");
exit(1);
}
struct sockaddr_in serverAddr;
bzero(&serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
// atoi, if not use this ,connect will fail.
serverAddr.sin_port = htons(atoi(argv[2]));
// use inet_addr to transfer the address
serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
//serverAddr.sin_addr.s_addr = htons(INADDR_ANY);
// connect
if (connect(clientSockFd, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr)) < 0) {
perror("connect");
exit(2);
}
// get the data from standard input. (keyboard)
char buf[1024] = {0};
while (1) {
read(0, buf, 1024);
write(clientSockFd, buf, 1024);
fflush(0);
}
return 0;
}