一、配置两台电脑的网络
1.查看物理机ip地址
(1)Win+R打开运行,输入cmd
![](https://i-blog.csdnimg.cn/blog_migrate/8d0edfe42c6260333c982dc20a846858.png)
(2)在cmd下输入ipconfig得到本机ip为192.168.3.2
![](https://i-blog.csdnimg.cn/blog_migrate/7180c7378705724f2a027a29a482c12e.png)
2.配置虚拟机ip
(1)打开虚拟机设置
![](https://i-blog.csdnimg.cn/blog_migrate/9fe56109f3f48c5da8faf492101f9164.png)
(2)设置网络连接模式
![](https://i-blog.csdnimg.cn/blog_migrate/e5a244631b29039269f2767547126ca5.png)
(3)在Ubuntu下设置ip
![](https://i-blog.csdnimg.cn/blog_migrate/1289517d145b0998bb81c6479eb510b3.png)
注意:物理机和虚拟机的IP不能一样,但必须处于同一网段。
我测试的时候物理机IP是192.168.3.2,虚拟机IP设置的是192.168.3.190。
(4)测试两台电脑是否连通
在终端下输入ping 192.168.3.X
二、编写服务器端和客户端程序
1.服务器端代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
const int port = 8888;
const char* ip = "192.168.64.190"; //服务器端IP
int main()
{
int ser_sock = socket(AF_INET, SOCK_STREAM, 0); //创建套接字,即创建socket
if(ser_sock < 0)
{
perror("socket");
return 1;
}
struct sockaddr_in addr; //绑定信息,即命名socket
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
/*inet_addr函数将用点分十进制字符串表示的
IPv4地址转化为用网络字节序整数表示的IPv4地址 */
if(bind(ser_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
{
perror("bind");
return 2;
}
int listen_sock = listen(ser_sock, 5); //监听socket
if(listen_sock < 0)
{
perror("listen");
return 3;
}
/*接受连接*/
struct sockaddr_in peer;
socklen_t peer_len;
char buf[1024];
int accept_fd = accept(ser_sock, (struct sockaddr*)&peer, &peer_len);
if(accept_fd < 0)
{
perror("accept");
return 4;
}
else
{
printf("connect from %s, port %d \n", inet_ntop(AF_INET,&peer.sin_addr, buf, 1024), ntohs(peer.sin_port));
}
while(1)
{
memset(buf, '\0', sizeof(buf));
ssize_t size = read(accept_fd, buf, sizeof(buf) - 1);
if(size > 0)
{
printf("client: %s\n", buf);
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
break;
}
printf("server:");
fflush(stdout);
size = read(0, buf, sizeof(buf) - 1);
if(size > 0)
{
buf[size - 1] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
break;
}
write(accept_fd, buf, strlen(buf));
}
close(ser_sock);
return 0;
}
2.客户端代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
const int port = 8888;
const char* ip = "192.168.64.190"; //服务器IP
int main()
{
int clt_sock = socket(AF_INET, SOCK_STREAM, 0); //创建套接字,即创建socket
if(clt_sock < 0)
{
perror("socket");
return 1;
}
struct sockaddr_in addr; //绑定信息,即命名socket
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
/*inet_addr函数将用点分十进制字符串表示的
IPv4地址转化为用网络字节序整数表示的IPv4地址 */
//发起连接
socklen_t addr_len = sizeof(addr);
int connect_fd = connect(clt_sock, (struct sockaddr*)&addr, addr_len);
if(connect_fd < 0)
{
perror("connect");
return 2;
}
char buf[1024];
while(1)
{
memset(buf, '\0', sizeof(buf));
printf("client please enter: ");
fflush(stdout);
ssize_t size = read(0, buf, sizeof(buf) - 1);
if(size > 0)
{
buf[size - 1] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
return 4;
}
// printf("client: %s\n", buf);
write(clt_sock, buf, strlen(buf));
size = read(clt_sock, buf, sizeof(buf));
if(size > 0)
{
buf[size] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
return 5;
}
printf("server: %s\n", buf);
}
close(clt_sock);
return 0;
}