Socket网络编程--聊天程序(1)
很早的一段时间,看了APUE和UNPv1了解了网络编程,但是但是只是看而已,没有具体的实践,趁现在没有什么事做,就来实践了解一下网络编程。写博客保存下来,方便以后用到的时候可以查到。
此次的聊天程序是迭代开发的。就是一步一步的修改成不同功能的聊天程序。
服务器server和客户端client
一对一,server和client是每人一句话聊天
讲解几个函数gethostbyname(),这个函数以前讲过就不多说了。
socket函数
#include <sys/socket.h>
int socket(int domain, int type, int protocol); //返回值:若成功则返回文件(套接字)描述符,若出错则返回-1
connect函数
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t len); //返回值:若成功则返回0,若出错则返回-1
bind函数
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t len); //返回值:若成功则返回0,若出错则返回-1
listen函数
#include <sys/socket.h>
int listen(int sockfd, int backlog); //返回值:若成功则返回0,若出错则返回-1,backlog表示连接请求数量
accept函数
#include <sys/socket.h>
int accept(int socdfd, struct sockaddr *restrict addr, socklen_t * restrict len); //若成功则返回文件(socket套接字)描述符,若出错则返回-1
recv函数
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags); //返回值:以字节计数的消息长度,若无可用消息或对方已经按序结束则返回0,若出错则返回-1
send函数
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags); //返回值:若成功则返回发送的字节数,若出错则返回-1
fgets函数
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
介绍完函数后,就直接贴出代码。
client.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <string.h> 5 #include <netdb.h> //for gethostbyname 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 #define MAX_BUF 4096 12 #define SERVER_PORT 12138 13 14 15 int main(int argc,char *argv[]) 16 { 17 int sockfd;//socket 18 char sendBuf[MAX_BUF],recvBuf[MAX_BUF]; 19 int sendSize,recvSize;//用于记录记录发送和接收到数据的大小 20 struct hostent * host; 21 struct sockaddr_in servAddr; 22 char username[32]; 23 char * p; 24 25 if(argc != 3) 26 { 27 perror("use: ./client [hostname] [username]"); 28 exit(-1); 29 } 30 p=username; 31 strcpy(p,argv[2]); 32 printf("username:%s\n",username); 33 host=gethostbyname(argv[1]); 34 if(host==NULL) 35 { 36 perror("fail to get host by name."); 37 exit(-1); 38 } 39 printf("Success to get host by name ...\n"); 40 41 //创建socket 42 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 43 { 44 perror("fail to establish a socket"); 45 exit(1); 46 } 47 printf("Success to establish a socket...\n"); 48 49 /*init sockaddr_in*/ 50 servAddr.sin_family=AF_INET; 51 servAddr.sin_port=htons(SERVER_PORT); 52 servAddr.sin_addr=*((struct in_addr *)host->h_addr); 53 bzero(&(servAddr.sin_zero),8); 54 55 /*connect the socket*/ 56 if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1) 57 { 58 perror("fail to connect the socket"); 59 exit(1); 60 } 61 printf("Success to connect the socket...\n"); 62 63 //send-recv 64 while(1) 65 { 66 printf("Input:"); 67 fgets(sendBuf,MAX_BUF,stdin); 68 send(sockfd,sendBuf,strlen(sendBuf),0); 69 memset(sendBuf,0,sizeof(sendBuf)); 70 recv(sockfd,recvBuf,MAX_BUF,0); 71 printf("Server:%s\n",recvBuf); 72 memset(recvBuf,0,sizeof(recvBuf)); 73 } 74 75 return 0; 76 }
server.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <string.h> 5 #include <netdb.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <sys/time.h> 9 #include <sys/un.h> 10 #include <sys/ioctl.h> 11 #include <sys/wait.h> 12 #include <netinet/in.h> 13 #include <arpa/inet.h> 14 15 16 #define SERVER_PORT 12138 17 #define BACKLOG 20 18 #define MAX_CON_NO 10 19 #define MAX_DATA_SIZE 4096 20 21 int main(int argc,char *argv[]) 22 { 23 struct sockaddr_in serverSockaddr,clientSockaddr; 24 char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE]; 25 int sendSize,recvSize; 26 int sockfd,clientfd; 27 int on=1; 28 int sinSize=0; 29 char username[32]; 30 31 if(argc != 2) 32 { 33 printf("usage: ./server [username]\n"); 34 exit(1); 35 } 36 strcpy(username,argv[1]); 37 printf("username:%s\n",username); 38 39 /*establish a socket*/ 40 if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) 41 { 42 perror("fail to establish a socket"); 43 exit(1); 44 } 45 printf("Success to establish a socket...\n"); 46 47 /*init sockaddr_in*/ 48 serverSockaddr.sin_family=AF_INET; 49 serverSockaddr.sin_port=htons(SERVER_PORT); 50 serverSockaddr.sin_addr.s_addr=htonl(INADDR_ANY); 51 bzero(&(serverSockaddr.sin_zero),8); 52 53 setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); 54 55 /*bind socket*/ 56 if(bind(sockfd,(struct sockaddr *)&serverSockaddr,sizeof(struct sockaddr))==-1) 57 { 58 perror("fail to bind"); 59 exit(1); 60 } 61 printf("Success to bind the socket...\n"); 62 63 /*listen on the socket*/ 64 if(listen(sockfd,BACKLOG)==-1) 65 { 66 perror("fail to listen"); 67 exit(1); 68 } 69 70 /*accept a client's request*/ 71 if((clientfd=accept(sockfd,(struct sockaddr *)&clientSockaddr, &sinSize))==-1) 72 { 73 perror("fail to accept"); 74 exit(1); 75 } 76 printf("Success to accpet a connection request...\n"); 77 printf(" %s join in!\n",inet_ntoa(clientSockaddr.sin_addr)); 78 while(1) 79 { 80 /*receive datas from client*/ 81 if((recvSize=recv(clientfd,recvBuf,MAX_DATA_SIZE,0))==-1) 82 { 83 perror("fail to receive datas"); 84 exit(1); 85 } 86 printf("%s\n",recvBuf); 87 memset(recvBuf,0,MAX_DATA_SIZE); 88 89 /*send datas to client*/ 90 printf("Server:"); 91 fgets(sendBuf,MAX_DATA_SIZE,stdin); 92 if((sendSize=send(clientfd,sendBuf,strlen(sendBuf),0))!=strlen(sendBuf)) 93 { 94 perror("fail to send datas"); 95 exit(1); 96 } 97 printf("Success to send datas\n"); 98 memset(sendBuf,0,MAX_DATA_SIZE); 99 } 100 101 return 0; 102 }
这些代码都比较简单,详细的讲解网上都有,这里就不多说了。
作者:无脑仔的小明 出处:http://www.cnblogs.com/wunaozai/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。有需要沟通的,可以站内私信,文章留言,或者关注“无脑仔的小明”公众号私信我。一定尽力回答。 |