My_socket.h
# Ifndef _ my_socket_h __# DEFINE _ my_socket_h __# include <stdio. h> # include <stdlib. h> # include <string. h> # include <unistd. h> # include <sys/socket. h> # include <sys/types. h> # include <netinet/in. h> # include <ARPA/inet. h> # define in # define out # define in_out # define my_tcp 1 # define my_udp 2 typedef struct sockaddr * PSA; typedef struct sockaddr_in SA; # define my_assert (flag, MSG) (FLAG )? Null: (fprintf (stdout, MSG), exit (exit_failure) // null represents void my_socket (Out int * local_sfd, int protocal, char * local_ip, int local_port); void my_listen (INT local_sfd, int backlog); void my_accept (Out int * peer_sfd, int local_sfd, out PSA peer_addr, in_out int * addr_len ); void my_connect (INT local_sfd, PSA peer_addr, int addr_len); void my_recv (Out int * recv_len, int peer_sfd, in_out void * base, int Len ); void my_send (Out int * send_len, int peer_sfd, void * base, int Len); void my_recvfrom (Out int * recvfrom_len, int peer_sfd, in_out void * base, int Len, out PSA peer_addr, in_out int * addr_len); void my_sendto (Out int * sendto_len, int peer_sfd, out void * base, int Len, PSA peer_addr, int addr_len ); void my_close (int sfd); # endif
My_socket.c
/* This code is used to simulate socket communication on a host. Therefore, the IP address is the same for the server and client. * To simplify the code, the port number is allocated in advance even on the client. In fact, the active party's port number can be allocated by the system, without binding * --> no matter the server or client, local socket * // * This code local_sfd represents the local socket descriptor. * The server is the socket used for listening, and the client is the socket * peer_sfd used for communication, representing the socket descriptor for communication with the other party. * For the server, the accept is returned as an outgoing parameter. for the client, it is a local socket */# include "my_socket.h" Void my_socket (Out int * local_sfd, int protocal, char * local_ip, int local_port) {my_assert (protocal = my_tcp | protocal = my_udp, "wrong Arg! Protocal is my_tcp or my_udp! \ N ");/* create a local socket */If (protocal = my_tcp) {my_assert (-1! = (* Local_sfd = socket (af_inet, sock_stream, 0), "tcp_socket init falure! \ N ");} else if (protocal = my_udp) {my_assert (-1! = (* Local_sfd = socket (af_inet, sock_dgram, 0), "udp_socket init failure! \ N ");}/* bind the local contact information to the local socket */SA local_addr; memset (& local_addr, 0, sizeof (SA); local_addr.sin_family = af_inet; outputs = htons (local_port); outputs = inet_addr (local_ip); my_assert (0 = BIND (* local_sfd, (PSA) & local_addr, sizeof (SA), "bind failure! \ N ");}/* --------------------------- TCP listener * // * server: Listen + accept */void my_listen (INT local_sfd, int backlog) {my_assert (0 = listen (local_sfd, backlog), "Listen failure! \ N ");} void my_accept (Out int * peer_sfd, int local_sfd, out PSA peer_addr, in_out int * addr_len) {my_assert (-1! = (* Peer_sfd = accept (local_sfd, peer_addr, addr_len), "accept failure! \ N ");}/* client: connect */void my_connect (INT local_sfd, PSA peer_addr, int addr_len) {int CNT = 0; // exit the program after 10 failures (-1 = connect (local_sfd, peer_addr, addr_len) {CNT ++; If (CNT = 10) {printf ("Connect failure! \ N "); exit (exit_failure);} Sleep (1) ;}/ * Recv and send */void my_recv (Out int * recv_len, int peer_sfd, in_out void * base, int Len) {my_assert (-1! = (* Recv_len = Recv (peer_sfd, base, Len, 0), "Recv error! \ N ");} void my_send (Out int * send_len, int peer_sfd, void * base, int Len) {my_assert (-1! = (* Send_len = Send (peer_sfd, base, Len, 0), "Send error! \ N ");}/* -------------------------- the following for UDP flood */void my_recvfrom (Out int * recvfrom_len, int peer_sfd, in_out void * base, int Len, out PSA peer_addr, in_out int * addr_len) {my_assert (-1! = (* Recvfrom_len = recvfrom (peer_sfd, base, Len, 0, peer_addr, addr_len), "recvfrom failure! \ N ");} void my_sendto (Out int * sendto_len, int peer_sfd, out void * base, int Len, PSA peer_addr, int addr_len) {my_assert (-1! = (* Sendto_len = sendto (peer_sfd, base, Len, 0, peer_addr, addr_len), "sendto failure! \ N ");}/* close */void my_close (int sfd) {my_assert (0 = close (SFD)," Close failure! \ N ");}
Compile it into a dynamic library
Gcc-FPIC-O my_socket.o-C my_socket.c gcc-shared-O libmy_socket.so.1.0 my_socket.o CP./libmy_socket.s0.3.1/libcd/libln-s libmy_socket.so.3.1 libmy_socket.so
// Test code
Server. c
# Include "my_socket.h" # define IP "192.168.0.138" # Define Port 8888int main (INT argc, char * argv []) {int fd_server, fd_client; int val; // use a 4-byte address space to transmit data int Len; my_socket (& fd_server, my_tcp, IP, Port); my_listen (fd_server, 5); my_accept (& fd_client, fd_server, null, null); printf ("accept success! \ N "); While (1) {my_recv (& Len, fd_client, (void *) & Val, sizeof (VAL); printf (" Recv data: % d \ n ", Val); my_send (& Len, fd_client, (void *) & Val, sizeof (VAL); printf (" % d has sent! \ N ", Val);} my_close (fd_client); my_close (fd_server); Return 0 ;}
// Test code
Client. c
# Include "my_socket.h" # define IP "192.168.0.138" # define my_port 6666 # define server_port 8888int main (INT argc, char * argv []) {/* socket */INT fd_client; my_socket (& fd_client, my_tcp, IP, my_port);/* connect */SA server_addr; memset (& server_addr, 0, sizeof (server_addr); server_addr.sin_family = af_inet; server_addr.sin_port = htons (server_port); server_addr.sin_addr.s_addr = inet_addr (IP); my_conn ECT (fd_client, (PSA) & server_addr, sizeof (SA); printf ("Connect success! \ N ");/* Send a data and return the data from the server */INT val_in, val_out, Len; while (scanf (" % d ", & val_in) = 1) {my_send (& Len, fd_client, (void *) & val_in, sizeof (INT); my_recv (& Len, fd_client, (void *) & val_out, sizeof (INT); printf ("Recv fron server: % d \ n", val_out);} my_close (fd_client); Return 0 ;}
// Compile
gcc -o server server.c -lmy_socket -I ../include
gcc -o client client.c -lmy_socket -I ../include
Encapsulate TCP and UDP into a dynamic library