TCP/IP network programming (1) Understanding network programming and sockets

Understand network programming and sockets

Network Programming and Sockets Overview

Network programming is writing programs to allow two networked computers to exchange data with each other.

In order to transmit data to a remote computer, you need to connect to the Internet, and programming sockets are the tools used to connect to the network.

Build socket

1. Call the soecket function to create a socket

#include<sys/socket.h>
int socket(int domain, int type, int protocol);
	
	——>成功返回文件描述符,失败返回-1

2. Call the bind function to assign an address to the socket.

#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);

	——>成功返回0,失败返回-1

3. Call the listen function to convert the socket into a state that can accept connections.

#include<sys/socket.h>
int listen(int sockfd, int backlog);

	——>成功时返回0,失败返回-1

4. Call the accept function to accept the connection request

#include<sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

	——>成功时返回文件描述符,失败返回-1

The socket creation process for accepting connection requests in network programming is summarized as follows:

1. Call the soecket function to create a socket

2. Call the bind function to assign an address to the socket.

3. Call the listen function to convert the socket into a state that can accept connections.

4. Call the accept function to accept the connection request

Writing Hello World server side

The server is a program that can accept connection requests

hello_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char *argv[])
{
	int serv_sock;
	int clnt_sock;

	struct sockaddr_in serv_addr;
	struct sockaddr_in clnt_addr;
	socklen_t clnt_addr_size;

	char message[]="Hello World!";
	
	if(argc!=2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
	
	serv_sock=socket(PF_INET, SOCK_STREAM, 0);
	if(serv_sock == -1)
		error_handling("socket() error");
	
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	serv_addr.sin_port=htons(atoi(argv[1]));
	
	if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1 )
		error_handling("bind() error"); 
	
	if(listen(serv_sock, 5)==-1)
		error_handling("listen() error");
	
	clnt_addr_size=sizeof(clnt_addr);  
	clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size);
	if(clnt_sock==-1)
		error_handling("accept() error");  
	
	write(clnt_sock, message, sizeof(message));
	close(clnt_sock);	
	close(serv_sock);
	return 0;
}

void error_handling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

Build request connection socket

The client program only has two steps: calling the socket function to create a socket and calling the connect function to issue a connection request to the server.

hello_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char* argv[])
{
	int sock;
	struct sockaddr_in serv_addr;
	char message[30];
	int str_len;
	
	if(argc!=3){
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
	
	sock=socket(PF_INET, SOCK_STREAM, 0);
	if(sock == -1)
		error_handling("socket() error");
	
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
	serv_addr.sin_port=htons(atoi(argv[2]));
		
	if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 
		error_handling("connect() error!");
	
	str_len=read(sock, message, sizeof(message)-1);
	if(str_len==-1)
		error_handling("read() error!");
	
	printf("Message from server: %s \n", message);  
	close(sock);
	return 0;
}

void error_handling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

Request connection function

#include<sys/socket.h>
int connect(int sockfd,struct sockaddr *serv_addr, socklen_t addrlen);

	——>成功返回0,失败返回-1

Runs under Linux platform

gcc hello_server.c -o hserver
./hserver 9190

Now the server has been opened, but the called accept function has not returned yet. Next, run the customer service.

gcc hello_client.c -o hclient
./hclient 192.168.233.20 9190
输出: Hello World!

Linux-based file operations

open a file

#include <sys/type.h>
#include <sys/stat.h>
#include <fcnt.h>

int open(const char *path, int flag);

	——>成功返回文件描述符,失败返回-1
    path   文件名的字符串地址
    flag   文件打开模式信息

file open mode

打开模式				含义
O_CREAT			   必要时创建文件
O_TRUNC			   删除全部现有数据
O_APPEND		   维持现有数据,保存末尾
O_RDONLY		   只读打开
O_WRONLY	   	   只写打开
O_RDWR			   读写打开

close file

#include<unistd.h>

int close(int fd);

	——>成功返回0,失败返回-1

Write data to file

#include<unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes);

	——>成功时返回写入的字节数,失败返回-1
        buf保存要传输数据的缓冲地址
        nbytes要传输的字节数

In the function definition, size_t is an unsigned int type declared through typedef. For ssize_t, s represents signed, and ssize_t is a signed int type.

lower_open.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void error_handling(char* message);

int main(void)
{
	int fd;
	char buf[]="Let's go!\n";
	
	fd=open("data.txt", O_CREAT|O_WRONLY|O_TRUNC);
	if(fd==-1)
		error_handling("open() error!");
	printf("file descriptor: %d \n", fd);

	if(write(fd, buf, sizeof(buf))==-1)
		error_handling("write() error!");

	close(fd);
	return 0;
}

void error_handling(char* message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

Read data from file

Corresponding to the write function, the read function is used to receive data.

#include<unistd.h>

ssize_t read(int fd, void *buf, size_t nbytes)
    
    ——>成功返回接受的字节数,失败返回-1

lower_read.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define BUF_SIZE 100

void error_handling(char* message);

int main(void)
{
	int fd;
	char buf[BUF_SIZE];
	
	fd=open("data.txt", O_RDONLY);
	if( fd==-1)
		error_handling("open() error!");
	
	printf("file descriptor: %d \n" , fd);
	
	if(read(fd, buf, sizeof(buf))==-1)
		error_handling("read() error!");

	printf("file data: %s", buf);
	
	close(fd);
	return 0;
}

void error_handling(char* message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

ps:

在文中出现好多次void error_handling(char* message)函数,这个是打印错误信息的,也可以用perror函数,例如
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int fd = open(data.txt, O_RDONLY);
    if(fd == -1)
    {
        perror("open:");
    }
}

For more information, click GitHub . Welcome readers to Star

⭐Academic exchange group Q 754410389 is being updated~~~

Guess you like

Origin blog.csdn.net/m0_63743577/article/details/132564036