从下一个星期开始到今年结束,本人会因为研究生入学考试的备考停止做项目9个月,今后的博客将大多数以介绍学习经验为主,本次主要来分享一下基础的socket Linux C程序编写经验。
话不多说,先上源码:
socket_client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MESSAGE "Hello, this is Donald Shallwing. I'm alread here, please wait for me in UESTC!\n"
#define BUF_SIZE 256
#define PORT 2018
#define BACK_LO "127.0.0.1"
int main(int argc, char **argv)
{
int client_fd = -1;
int connect_fd = -1;
char buffer[BUF_SIZE];
socklen_t client_len;
struct sockaddr_in server_addr;
int client_read_fd = -1;
int client_write_fd = -1;
client_fd = socket( AF_INET, SOCK_STREAM, 0);
if(client_fd < 0)
{
printf("\nFail to create a new client socket [%d]: %s\n", client_fd, strerror(errno) );
}
else
{
printf("\nCreate a new client socket [%d]\n", client_fd);
}
memset( &server_addr, 0, sizeof(server_addr) );
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
inet_aton( BACK_LO, &server_addr.sin_addr );
connect_fd = connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr) );
if(connect_fd < 0)
{
printf("Fail to connect with the server computer [%d]: %s\n", connect_fd, strerror(errno));
return connect_fd;
}
else
{
printf("Complete to connect with the server computer\nIP:%s\n", inet_ntoa(server_addr.sin_addr) );
}
//read & write
client_read_fd = read( client_fd, buffer, sizeof(buffer) );
if(client_read_fd < 0)
{
printf("Fail to read the buffer of the server computer [%d]: %s\n", client_read_fd, strerror(errno));
}
else
{
printf("The content of the buffer in server computer is:\n%s\n", buffer);
}
client_write_fd = write( client_fd, MESSAGE, sizeof(MESSAGE) );
if(client_write_fd < 0)
{
printf("Fail to write MESSAGE [%d]: %s\n", client_write_fd, strerror(errno) );
return client_write_fd;
}
else
{
printf("Complete to write MESSAGE in client_fd!\n\n");
}
close(client_fd);
close(client_write_fd);
close(client_read_fd);
close(connect_fd);
return 0;
}
socket_server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LISTEN_PORT 2018
#define BUF_SIZE 256
#define BACKLOG 8
#define MESSAGE "Hello,my name is socket,I originate from Ubuntu OS!\n"
/*struct sockaddr_in{
sa_family_t sin_family;
unit16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}*/
int main(int argc, char **argv)
{
socklen_t client_addrlen;
int bind_fd = -1;
int listen_fd = -1;
int client_fd = -1;
int client_read_fd = -1;
int client_write_fd = -1;
int reuse = 1;
char buffer[BUF_SIZE];
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
listen_fd = socket(AF_INET, SOCK_STREAM , 0);
if(listen_fd < 0)
{
printf("\nCan't create a listener fd [%d]: %s\n", listen_fd,
strerror(errno));
return listen_fd;
}
printf("\nA socket has been created: [%d]\n", listen_fd);
//Close the port after halting the progress or run it again
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, reuse);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( LISTEN_PORT );
server_addr.sin_addr.s_addr = htonl( INADDR_ANY );
bind_fd = bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(bind_fd < 0)
{
printf("Fail to bind the port [%d]: %s\n", bind_fd,
strerror(errno));
return bind_fd;
}
else
{
printf("Socket[%d] bind successfully!\n\n", listen_fd );
}
listen(listen_fd, BACKLOG);
while(1)
{
//Accept a client
printf("Start connecting...\n\n");
client_fd = accept( listen_fd, (struct sockaddr*)&client_addr, &client_addrlen);
if( client_fd < 0 )
{
printf("Fail to accept client host [%d]: %s\n", client_fd,
strerror(errno));
break;
}
else
{
printf("A new client host has connected\nIP:%s port:%d \n",
inet_ntoa( client_addr.sin_addr ), ntohs(client_addr.sin_port) );
}
//Server read & write
memset(buffer, 0, sizeof(buffer));
client_write_fd = write(client_fd, MESSAGE, sizeof(MESSAGE) );
if( client_write_fd < 0)
{
printf("Fail to write the MESSAGE [%d]: %s\n", client_write_fd, strerror(errno) );
continue;
}
else
{
printf("Complete to send MESSAGE!\n");
}
memset(buffer, 0, sizeof(buffer));
client_read_fd = read( client_fd, buffer, sizeof(buffer) );
if( client_read_fd < 0 )
{
printf("Fail to read in the client host[%d]: %s", client_read_fd,
strerror(errno) );
}
else
{
if( client_read_fd == 0 )
{
printf("The client host[%d][%d] is disconnected!\n", client_fd,
ntohl(client_addr.sin_addr.s_addr) );
}
else
{
printf("The content of the host is:\n%s\n\n", buffer);
}
}
}
close( listen_fd );
close( client_fd );
close( client_read_fd );
close( bind_fd );
return 0;
}
以上是本人写的第一个socket程序。read和write不是socket编程中特有的函数,相应的,socket编程里还有与之类似的recv和send函数,也是用来对文件描述符进行读写的,用法比read和write简单。后来的编程中,本人逐渐用recv和send函数代替了read和write。
基础的socket编程只用达到一个目标,就是实现客户端和服务器之间简单的通信,实现此目标的核心便是建立服务器和客户端之间的socket连接,而建立连接的基础便是理清服务器端和客户端建立的流程。
服务器端的建立:
客户端的建立:
经常写socket程序的人就很清楚,socket通信总结起来,客户端与服务器端在程序里面无外乎各有两个动作:服务器端先应该搭建好服务器的框架,然后再去接收客户端文件描述符并与之通信;客户端先搭建好socket并与连接上服务器,然后再去读写服务器端发来的数据。这些是socket通信程序的统一流程(本人上一篇有关FTP文件上传与下载的博客中,客户端的行为不也是先搭建好socket然后利用FTP命令来与FTP服务器之间进行数据传输的吗)
初学者接触Unix网络socket编程,会表现出无从下手,思维混乱的情况,这很正常,本人在此讲述一下初次学习socket编程的方法和今后写socket程序的习惯。
以上便是本人学习socket编程中的一些细节与方法,希望读者阅读完此篇博客之后有所收获,编程更上一层楼!