计网实验(一),基于socket编程的通信程序

socket套接字编程

        socket编程换句话说是套接字编程,像一个套子将两个计算机进行连接。

服务端的代码编写流程如下:WSAsocket()->bind()->listen()->accept()->send()/recv()->closesocket()->WSACleanup()

客户端的代码编写流程如下:WSAsocket()->socket()->connect()->recv()/send()->closesocket()->WSACleanuo()

基于C语言Winsock-TCP的通信

        以下两个程序,需要在vc++6.0中,选择Win32 Console Application中的简单hello world或者空项目,然后先运行server,后运行client。便可以实现基本的socket通信。记住修改相应的IP和端口。

server:

client:

输入任意信息后:

//tcp_client
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET clientSocket;
    struct sockaddr_in serverAddr;

    // Create socket
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        perror("socket creation failed");
        WSACleanup();
        return 1;
    }

    // Set server address
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(1234);  // Use the same port as the server
    serverAddr.sin_addr.s_addr = inet_addr("192.168.137.1");  // Replace with the server's IP address

    // Connect to the server
    if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        perror("connection failed");
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    printf("Connected to the server\n");

    char buffer[1024];
    while (1) {
        printf("Enter a message (or 'quit' to exit): ");
        gets(buffer);

        // Send the message to the server
        send(clientSocket, buffer, strlen(buffer), 0);

        if (strcmp(buffer, "quit") == 0) {
            break;  // Exit the loop if the user enters 'quit'
        }
    }

    // Close socket and cleanup
    closesocket(clientSocket);
    WSACleanup();

    return 0;
}
//tcp_server
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建套接字
    SOCKET sLisent = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    // 对sockaddr_in结构体填充地址、端口等信息
    struct sockaddr_in ServerAddr;
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY; // Listen on all available network interfaces
    ServerAddr.sin_port = htons(1234);

    // 绑定套接字与地址信息
    bind(sLisent, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr));

    // 端口监听
    listen(sLisent, SOMAXCONN);

    printf("Server is listening...\n");

    // 获取连接请求
    struct sockaddr_in ClientAddr;
    int nSize = sizeof(ClientAddr);

    SOCKET sClient = accept(sLisent, (SOCKADDR *)&ClientAddr, &nSize);
    printf("Client connected\n");

    // 接收消息并显示在屏幕上
    char buffer[1024];
    while (1) {
        int bytesReceived = recv(sClient, buffer, sizeof(buffer), 0);
        if (bytesReceived <= 0) {
            break;
        }
        buffer[bytesReceived] = '\0';
        printf("Received from client: %s\n", buffer);

        // 发送消息到客户端(可选,如果要回应客户端)
        // send(sClient, buffer, bytesReceived, 0);
    }

    // 关闭套接字
    closesocket(sClient);
    closesocket(sLisent);

    WSACleanup();

    return 0;
}

基于python语言Winsock-TCP的通信

#server
import socket
 
sk = socket.socket()
#maybe? waiting test
ip_port = ('192.168.137.1', 55555)
#bind listen
sk.bind(ip_port)
#the max number of connection
sk.listen(5)
#waring message
print('Running')
#get data
conn, address = sk.accept()
while True:
    print(conn.recv(1024).decode())
#close connection
conn.close()


#client
import socket
 
sk = socket.socket()
#bind ip and port
ip_port = ('192.168.137.1', 55555)
#connect server
sk.connect(ip_port)
#get server data
while True:
    send = input('What :')
    sk.send(send.encode())

发送任意信息:

socket编程下的可视化python程序(基于UDP模式)

需要先进行本地和目标IP设置,然后进行发送,有时候需要关闭计算机的防火墙。

参考#https://blog.csdn.net/qq_41500251/article/details/90114802
import tkinter as tk
import socket
import threading

sk_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sk_send = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 
ip_port_recv = ('127.0.0.1',55555)
ip_port_send = ('127.0.0.1',55555)
 
def loop():
    while True:
        var = sk_recv.recv(1024).decode()
        t.insert('insert', var + '\n')

root = tk.Tk()
root.title('通信系统')
root.geometry('800x600')
root.config(background='#F8FEEE')

labe = tk.Label(root, text='消息框:')
labe.pack()    
t = tk.Text(root, height=10)
t.pack()


#config my ip
def conf_ip():
    #create sub windon
    top = tk.Toplevel()
    top.title('设置本地 IP')
    top.geometry('300x100')
 
    #a entry
    e = tk.Entry(top)
    e.pack()
 
    #the function of button
    def confirm():
        global ip_port_recv, var_ip, sk_recv
        var = e.get()
        #change ip
        ip_port_recv = (var, 55555)
        #change label var
        var_ip.set('本地IP:' + var)
        #bing port
        sk_recv.bind(ip_port_recv)
        #loop to recive data
        t1 = threading.Thread(target=loop)
        t1.setDaemon(True)
        t1.start()
        #close subwindon
        top.destroy()
 
    #a button
    b = tk.Button(top, text='确定', command=confirm)
    b.pack()


#config his/her id
def conf_send():
    top = tk.Toplevel()
    top.title('设置目标IP')
    top.geometry('300x100')
 
    e = tk.Entry(top)
    e.pack()
 
    def confirm():
        global ip_port_send, var_send
        var = e.get()
        ip_port_send = (var, 55555)
        var_send.set('目标IP:' + var)
        top.destroy()
    b = tk.Button(top, text='确定', command=confirm)
    b.pack()


#Edit my id
def edit_id():
    top = tk.Toplevel()
    top.title('设置 ID')
    top.geometry('300x100')
 
    e = tk.Entry(top)
    e.pack()
 
    def confirm():
        global var_name, name
        var_name.set('我的ID:' + e.get())
        name.set(e.get())
        top.destroy()
    b = tk.Button(top, text='确定', command=confirm)
    b.pack()


#create menu
menubar = tk.Menu(root)
ip_menu = tk.Menu(menubar, tearoff=0)
 
#config menu and add submenu
menubar.add_cascade(label='设置', menu=ip_menu)
ip_menu.add_command(label='设置本地 IP', command=conf_ip)
ip_menu.add_command(label='设置目标 IP', command=conf_send)
ip_menu.add_command(label='设置 ID', command=edit_id)
 
#show menu
root.config(menu = menubar)
 
#a friendly label
label = tk.Label(root, text='输入框:')
label.pack()

entry = tk.Entry(root)
entry.pack()
 
def insert_point():
    global name
    var = entry.get()
    message = name.get() + ' : ' + var
    t.insert('insert', message + '\n')
    sk_send.sendto(message.encode(), ip_port_send)
    entry.delete(0, tk.END)
    
button = tk.Button(root, text='发送', command=insert_point)
button.pack()

#some var
#my ip
var_ip = tk.StringVar()
#his/her ip
var_send = tk.StringVar()
#my id
var_name = tk.StringVar()
name = tk.StringVar()
 
#some friendly labels
label1 = tk.Label(root, textvariable=var_ip)
label2 = tk.Label(root, textvariable=var_send)
label3 = tk.Label(root, textvariable=var_name)
label1.pack()
label2.pack()
label3.pack()

    
root.mainloop()

对于代码的个人解释:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想造一顶白cap

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值