一、代码
Socket Server端:
/****************************
*****简单的socket server程序*
*****************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/select.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<errno.h>
#define MAX_LINE 128
#define LISTENQ 20
#define PORT 8888
/*Socket Client*/
int main(int argc, char *argv[])
{
printf("%d,%s\n",argc,argv[1]);
int socket_fd = 0;
int listen_fd = 0;
int connfd;
int con_fd = 0;
int fd_flag = 0;
int buflen = 0;
socklen_t length;
fd_set read_fd;
char buf[1024] = {0};
char Mesg[] = "HelloWorld";
char Recv[MAX_LINE] = {0};
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
struct sockaddr_in server_addr, client_addr;
if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("create socket error:\n");
exit(EXIT_FAILURE);
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
if(bind(socket_fd, (struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)
{
perror("bind error:%d\n");
exit(EXIT_FAILURE);
}
if(listen(socket_fd,LISTENQ) == -1)
{
perror("listen error:%d\n");
exit(EXIT_FAILURE);
}
else
{
printf("listen alright\n");
}
while(1)
{
FD_ZERO(&read_fd);
FD_SET(socket_fd, &read_fd);
fd_flag = select(socket_fd+1, &read_fd, NULL, NULL, NULL);
if(FD_ISSET(socket_fd, &read_fd))
{
length = sizeof(client_addr);
printf("accept connection\n");
if((connfd = accept(socket_fd, (struct sockaddr *)&client_addr,&length)) < 0)
{
perror("Server accept meet failure\n");
exit(EXIT_FAILURE);
}
printf("Accept client ip:%s,port:%d\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
if(read(connfd, buf, MAX_LINE) <= 0)
{
perror("Server read buf meet failure\n");
exit(EXIT_FAILURE);
}
printf("Server has received buf:%s\n",buf);
int length = write(connfd, Mesg, strlen(Mesg));
printf("Write buf %s to client\n",Mesg);
}
}
close(socket_fd);
close(connfd);
return 0;
}
Socket Client端:
/************************
简单的Sock Client端程序
*************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/select.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<errno.h>
#define MAX_LINE 128
#define PORT 8888
/*Socket Client*/
int main(int argc, char *argv[])
{
printf("%d,%s\n",argc,argv[1]);
int socket_fd = 0;
int fd_read = 0;
int fd_write = 0;
int buflen = 0;
int write_len = 0;
fd_set read_fd;
char Recv[MAX_LINE] = {0};
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
struct sockaddr_in client_addr;
if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Socket initialization meet failure.\n");
exit(EXIT_FAILURE);
}
bzero(&client_addr, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(PORT);
if(inet_pton(AF_INET, argv[1], &client_addr.sin_addr) <= 0)
{
perror("Addr transverse meet failure.\n");
exit(EXIT_FAILURE);
}
if(connect(socket_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0)
{
perror("Connect meet error\n");
exit(EXIT_FAILURE);
}
write_len = write(socket_fd, argv[2], strlen(argv[2]));
printf("Write buf to Server:%s and Buf length is:%d\n",argv[2], write_len);
FD_ZERO(&read_fd);
FD_SET(socket_fd, &read_fd);
fd_read = select(socket_fd+1, &read_fd, NULL, NULL, &timeout);
if(FD_ISSET(socket_fd,&read_fd))
{
printf("Select Read FD is ready and fd is:%d\n",socket_fd);
buflen = read(socket_fd, Recv, MAX_LINE);
if(buflen)
{
printf("Read ok and buf is:%s\n",Recv);
}
}
if(close(socket_fd) == 0)
{
printf("close fd right\n");
}
return 0;
}
二、Server端的编码步骤:
1.socket函数初始化一个基于TCP的socket_fd套接字;
2.通过bind函数绑定套接字结构体,指定IPV4协议族,监听本机的网口IP地址和指定端口;
3.listen函数开始监听CLIENT的请求;
4.然后通过在while循环中,select函数取获取可用的readfd集,可设置timeout;
5.通过FD_ISSET和select配合,发现可用的套接字,通过accept函数获取与client的连接;
6.通过read函数读取client发过来的数据;
7.通过write回复client消息;
8.close套接字;
三、Client端的编码步骤:
1.socket函数初始化一个基于TCP的socket_fd套接字;
2.直接通过connect函数往指定IP地址,端口,协议族发送连接请求,若连接成功则继续;
3.连接成功后,通过write函数往server端发送数据消息;
4.通过select函数取获取可读readfd,表明read可读权限后,调用read函数,获取server端发来的消息;
5.close套接字;
注:select函数中最后一个参数timeout可决定select函数是否阻塞;