网络通信编程即编写通过计算机与其他程序之间进行通讯的程序,相互通信的程序中一方可以称为客户端程序,另一方称为服务程序,应用系统提供Socket编程接口可以编写自己的网络程序。
一 通过TCP/IP协议进行传输
TCP:为应用程序提供可靠的通信连接。适合一次传输大批的数据情况。并使用于要求得到的响应程序。
UDP:提供无线连接通信,且对传送包进行可靠性保证。适合一次传输少量的数据,可靠性则由应用层来负责。
二 Socket套接字
网络通信编程通过socket接口来进行的。socket接口是TCP/IP网络的API,包含了一整套的调用接口和数据结构定义,他给应用程序提供了如使用TCP/UDP等网络协议进行通讯的手段。
每一个socket都用一个半相关的描述(协议,本地地址,本地端口)来表示;一个完整的套接字则用一个相关描述(协议,本地地址,本地端口,远程地址,远程端口)来表示。
常见的socket有3种类型如下:
- 流式套接字socket(SOCK_STREAM)
流式套接字提供面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收.
2.数据报套接字socke(SOCK_DGRSM)
数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠,无差错的。
3原始套接字
允许对底层协议如IP或ICMP进行直接访问,它功能强大使用较为不便,主要用于一些协议的开发.
三 客户/服务模式
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器,及客户向服务器提出请求,服务器接收到请求后,提供相应的服务。
编程过程
服务器端:socket-bind-listen-accept-recv/recvfrom-send/sendto-close
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 4024
#define MAX_QUE_CONN_NM 5
int main()
{
struct sockaddr_in server_addr,client_addr;
int sockfd,recvbytes;
int sin_size,client_fd;
char buffer[BUFFER_SIZE];
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(PORT);
server_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
int i=1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1)
{
perror("bind\n");
exit(1);
}
printf("bind success\n");
if(listen(sockfd,MAX_QUE_CONN_NM)==-1)
{
perror("listen\n");
exit(1);
}
printf("Listen......\n");
if((client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&sin_size))==-1)
{
perror("recv\n");
exit(1);
}
printf("server get connection from %s\n",(char *)inet_ntoa(client_addr.sin_addr));
memset(buffer,0,sizeof(buffer));
if((recvbytes=recv(client_fd,buffer,BUFFER_SIZE,0))==-1)
{
perror("recv");
exit(1);
}
char *str1="hello server";
char *str2="hello ABC";
if(strncmp(buffer,str1,strlen(str1))==0)
{
printf("receive a message:%s\n",buffer);
send(client_fd,"hello client",12,0);
printf("send a message:hello client\n");
}
if(strncmp(buffer,"exit",4)==0)
{
exit(0);
close(sockfd);
}
}
客户端:socket-connect-send/sendto-recv/recvfrom-close
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define MAXLINE 4096
int main(int argc, char** argv)
{
int sockfd, n,rec_len;
char recvline[4096], sendline[4096];
char buf[MAXLINE];
struct sockaddr_in servaddr;
if( argc != 2){
printf("usage: ./client <ipaddress>\n");
exit(0);
}
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(4321);
if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
printf("inet_pton error for %s\n",argv[1]);
exit(0);
}
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
printf("send msg to server: \n");
fgets(sendline, 4096, stdin);
if( send(sockfd, sendline, strlen(sendline), 0) < 0)
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) {
perror("recv error");
exit(1);
}
buf[rec_len] = ‘\0‘;
printf("Received : %s ",buf);
close(sockfd);
exit(0);
}