This log is to start from a running example, once you can successfully see the successful operation of the program, then the next event I think should be asked why. It seems so much easier to understand and master.
The concept of the socket program is not much written here, but I believe that if you can read this whole article, I believe there will be no more such doubts.
The following will write a C/s structure of the program, the main function is that the client will send some messages to the server, and when the server receives a client request, and send a response message to the client.
The SERVER.C code is as follows:
#include <stdio .h>
#include < Stdlib .h>
#include < errno .h>
#include < string .h>
#include < sys/types.h>
#include < netinet/in.h>
#include < sys/socket.h>
#include < sys/wait.h>
#define Servport 3333
#define BACKLOG 10
#define MAXSIZE 1024
int main () {
int sockfd,client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
Creating sockets
if ((SOCKFD = socket (af_inet,sock_stream,0)) = = 1) {
Perror ("Socket create failed!");
Exit (1);
}
Binding port Address
my_addr.sin_family = af_inet;
My_addr.sin_port = htons (Servport);
MY_ADDR.SIN_ADDR.S_ADDR = Inaddr_any;
Bzero (& (My_addr.sin_zero), 8);
if (Bind (SOCKFD, (struct sockaddr*) &my_addr, sizeof (struct sockaddr)) = = 1) {
Perror ("Bind error!");
Exit (1);
}
Listening port
if (Listen (SOCKFD, BACKLOG) = = 1) {
Perror ("Listen error");
Exit (1);
}
while (1) {
int sin_size = sizeof (struct sockaddr_in);
if ((client_fd = Accept (SOCKFD, (struct sockaddr*) &remote_addr,&sin_size)) = = 1) {
Perror ("Accept error!");
Continue
}
printf ("Received a connection from%s/n", (char*) Inet_ntoa (REMOTE_ADDR.SIN_ADDR));
Child process Segment
if (!fork ()) {
Accept client-Sent request information
int rval;
Char Buf[maxsize];
if ((Rval = Read (CLIENT_FD, buf, MAXSIZE)) < 0) {
Perror ("Reading stream error!");
Continue
}
printf ("%s/n", buf);
Sending information to the client
char* msg = "Hello,mr Hqlong, you are connected!/n";
if (Send (CLIENT_FD, MSG, strlen (msg), 0) = = 1) perror ("Send error!");
Close (CLIENT_FD);
Exit (0);
}
Close (CLIENT_FD);
}
return 0;
}
Compiling and starting a service
hqlong@ubuntu:~$ gcc server.c-o Server
Hqlong@ubuntu:~$./server &
Here our server is already running as a service background, if you want to know the running state of the service in the background, you may use Netstat to view it.
hqlong@ubuntu:~/t$ NETSTAT-NL | grep 3333
TCP 0 0 0.0.0.0:3333 0.0.0.0:* LISTEN
You can see that port 3333 is already listening, which indicates that the service has started.
To test whether the server can accept client requests, you can use Telnet to test.
hqlong@ubuntu:~$ telnet 127.0.0.1 3333
Trying 127.0.0.1 ...
Received a connection from 127.0.0.1
Connected to 127.0.0.1.
Escape character is ' ^] '.
Test
Test
HELLO,MR Hqlong, you are connected!
Connection closed by foreign host.
As you can see, we used Telnet to connect to the server we just started, and then we sent a message "test" to the server, and the server, after receiving this message, sent a response message to the client telling us that we were connected.
The next step is to write your own client program, which, like the Telnet test above, sends a message to the server that sends a response message to the client after receiving this message.
The code is as follows: client.c
#include < stdio .h>
#include < Stdlib .h>
#include < errno .h>
#include < string .h>
#include < sys/types.h>
#include < netinet/in.h>
#include < sys/socket.h>
#include < sys/wait.h>
#define Servport 3333
#define MAXDATASIZE 100
#define SERVER_IP "127.0.0.1"
#define DATA "This is a client message"
int main (int argc, char* argv[]) {
int SOCKFD, recvbytes;
Char Buf[maxdatasize];
struct Hostent *host;
struct sockaddr_in serv_addr;
if ((SOCKFD = socket (af_inet, sock_stream, 0)) = = 1) {
Perror ("Socket error!");
Exit (1);
}
Bzero (&serv_addr,sizeof (SERV_ADDR));
serv_addr.sin_family = af_inet;
Serv_addr.sin_port = htons (Servport);
Serv_addr.sin_addr.s_addr= inet_addr (SERVER_IP);
If Connect (sockfd, (struct sockaddr *) &serv_addr,sizeof (struct sockaddr)) = = 1) {
Perror ("Connect error!");
Exit (1);
}
Write (Sockfd,data, sizeof (DATA));
if ((Recvbytes = recv (SOCKFD, buf, maxdatasize,0)) = = 1) {
Perror ("recv error!");
Exit (1);
}
Buf[recvbytes] = '/0 ';
printf ("Received:%s", buf);
Close (SOCKFD);
return 0;
}
Compile run
hqlong@ubuntu:~$ gcc Client.c-o Client
hqlong@ubuntu:~$./client
Received a connection from 127.0.0.1
HELLO,MR Hqlong, you are connected!
Connection closed by foreign host.
The above is the entire server-side and client program writing.
The above illustration shows a typical socket system call that is made when a program uses a connection-oriented protocol (TCP). The server program establishes a socket and calls the BIND function to associate this socket with the local protocol port, then puts this socket parameter in passive listening mode with the listen and accept functions and receives the connection.
The client program also creates a socket, and then calls the Connect function to start the network conversation. After the client and the server establish a connection, you can use the read, write and other functions to communicate.
For specific function details, please refer to the Linux C function manual