网络通信
BSD Socket网络通信编程
例子:简单的TCP聊天程序
TcpServer.c
/*10.177.72.129 server*/
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
int sockfd,connfd,size;
char buffer[1024];
struct sockaddr_in myaddr;
//创建套接字
sockfd=socket(AF_INET,SOCK_STREAM,0);
//初始化服务器地址结构
//将myaddr全部置为0
bzero(&myaddr,sizeof(myaddr));
//指定为internet协议簇
myaddr.sin_family=AF_INET;
//host->net short
//将short类型端口2121由主机字节序(小端)转换为网络字节序(大端)
myaddr.sin_port=htons(2121);
//将ip地址由字符串转换为二进制形式
inet_aton("10.177.2.196",&myaddr.sin_addr);
//绑定套接字到指定的地址和端口
if(bind(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr))<0)
{
perror("绑定失败");
exit(EXIT_FAILURE);
}
//完成此步bind之后,该socket拥有了本地IP地址,端口,通信协议,不能接收客户端的请求,但可以向服务器发起连接。
// 监听套接字,等待客户端连接
if(listen(sockfd,3)<0)
{
perror("监听错误");
exit(EXIT_FAILURE);
}
printf("监听中...\n");
//接收客户端连接
if((connfd=accept(sockfd,(struct sockaddr *)&myaddr,&size))<0)
{
perror("接受连接失败");
exit(EXIT_FAILURE);
}
printf("连接的文件描述符 fd:%d\n",connfd);
if(connfd>0)
{
printf("client ip:%s\n",inet_ntoa(myaddr.sin_addr));
printf("client port:%d\n",ntohs(myaddr.sin_port));
}
//读写数据
while(1)
{
read(connfd,buffer,1024);
printf("%s",buffer);
if(strncmp("end",buffer,3)==0)
break;
}
//关闭连接和套接字
close(connfd);
close(sockfd);
return 0;
}
TcpClient.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
int main()
{
int sockfd, ret, cnt;
char buf[1024];
struct sockaddr_in myaddr;
// 创建套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("创建套接字失败");
exit(EXIT_FAILURE);
}
// 设置服务器的 IP 地址和端口号
bzero(&myaddr, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(2121);
if (inet_pton(AF_INET, "10.177.2.196", &myaddr.sin_addr) < 0)
{
printf("\n无效的地址/地址不支持\n");
return -1;
}
// 连接服务器
if (connect(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0)
{
printf("\n连接失败\n");
return -1;
}
// 读取输入并发送给服务器
while (1)
{
cnt = read(0, buf,sizeof(buf));
send(sockfd, buf, cnt, 0);
if (strncmp(buf, "end", 3) == 0)
break;
}
close(sockfd);
return 0;
}
改为UDP
将客户端代码从TCP改为UDP的方式,需要对代码进行适当的修改。以下是修改后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
int main()
{
int sockfd, ret, cnt;
char buf[1024];
struct sockaddr_in myaddr, serveraddr;
// 创建套接字
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == 0)
{
perror("创建套接字失败");
exit(EXIT_FAILURE);
}
// 设置服务器的 IP 地址和端口号
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(2121);
if (inet_pton(AF_INET, "10.177.2.196", &serveraddr.sin_addr) < 0)
{
printf("\n无效的地址/地址不支持\n");
return -1;
}
// 读取输入并发送给服务器
while (1)
{
cnt = read(0, buf, sizeof(buf));
sendto(sockfd, buf, cnt, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if (strncmp(buf, "end", 3) == 0)
break;
}
close(sockfd);
return 0;
}
将 socket
函数的第二个参数由 SOCK_STREAM
改为 SOCK_DGRAM
,即可创建一个UDP套接字。然后,使用 sendto
函数发送数据到服务器,而不是使用 send
函数。
请注意,UDP是一种无连接的协议,不保证数据的可靠传输和顺序性。因此,在使用UDP进行通信时,需要考虑数据丢失、乱序等问题,并根据实际需求进行适当的处理。